]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
update to 2015.04-rc1
authorLothar Waßmann <LW@KARO-electronics.de>
Mon, 9 Mar 2015 08:21:53 +0000 (09:21 +0100)
committerLothar Waßmann <LW@KARO-electronics.de>
Mon, 9 Mar 2015 08:21:53 +0000 (09:21 +0100)
419 files changed:
.gitignore
Kconfig
README
arch/arm/Kconfig
arch/arm/config.mk
arch/arm/cpu/arm926ejs/cpu.c
arch/arm/cpu/arm926ejs/mxs/clock.c
arch/arm/cpu/arm926ejs/mxs/mxs.c
arch/arm/cpu/arm926ejs/mxs/spl_boot.c
arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
arch/arm/cpu/arm926ejs/mxs/timer.c
arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock_am33xx.c
arch/arm/cpu/armv7/am33xx/ddr.c
arch/arm/cpu/armv7/am33xx/sys_info.c
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/cpu.c
arch/arm/cpu/armv7/lowlevel_init.S
arch/arm/cpu/armv7/mx5/clock.c
arch/arm/cpu/armv7/mx5/lowlevel_init.S
arch/arm/cpu/armv7/mx5/soc.c
arch/arm/cpu/armv7/mx6/asm-offsets.c [new file with mode: 0644]
arch/arm/cpu/armv7/mx6/clock.c
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/cpu/armv7/omap-common/boot-common.c
arch/arm/cpu/armv7/omap-common/lowlevel_init.S
arch/arm/cpu/armv7/omap-common/reset.c
arch/arm/cpu/armv7/omap-common/timer.c
arch/arm/dts/imx6qdl.dtsi [new file with mode: 0644]
arch/arm/dts/mx28.dtsi [new file with mode: 0644]
arch/arm/dts/mx51.dtsi [new file with mode: 0644]
arch/arm/dts/mx53.dtsi [new file with mode: 0644]
arch/arm/dts/mx6dl.dtsi [new file with mode: 0644]
arch/arm/dts/mx6q.dtsi [new file with mode: 0644]
arch/arm/imx-common/iomux-v3.c
arch/arm/imx-common/timer.c
arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/da8xx-fb.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/ddr_defs.h
arch/arm/include/asm/arch-am33xx/gpio.h
arch/arm/include/asm/arch-am33xx/mmc_host_def.h
arch/arm/include/asm/arch-exynos/system.h
arch/arm/include/asm/arch-mx5/clock.h
arch/arm/include/asm/arch-mx5/crm_regs.h
arch/arm/include/asm/arch-mx5/imx-regs.h
arch/arm/include/asm/arch-mx5/iomux-mx51.h
arch/arm/include/asm/arch-mx5/iomux-mx53.h
arch/arm/include/asm/arch-mx5/sys_proto.h
arch/arm/include/asm/arch-mx6/clock.h
arch/arm/include/asm/arch-mx6/crm_regs.h
arch/arm/include/asm/arch-mx6/imx-regs.h
arch/arm/include/asm/arch-mx6/regs-ocotp.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx6/sys_proto.h
arch/arm/include/asm/arch-mxs/clock.h
arch/arm/include/asm/arch-mxs/regs-clkctrl-mx28.h
arch/arm/include/asm/arch-mxs/regs-digctl.h
arch/arm/include/asm/arch-mxs/regs-i2c.h
arch/arm/include/asm/arch-mxs/regs-lcdif.h
arch/arm/include/asm/arch-mxs/regs-ocotp.h
arch/arm/include/asm/arch-mxs/regs-pinctrl.h
arch/arm/include/asm/arch-mxs/regs-power-mx28.h
arch/arm/include/asm/arch-mxs/regs-rtc.h
arch/arm/include/asm/arch-mxs/regs-ssp.h
arch/arm/include/asm/arch-mxs/regs-timrot.h
arch/arm/include/asm/arch-mxs/regs-usbphy.h
arch/arm/include/asm/arch-mxs/sys_proto.h
arch/arm/include/asm/emif.h
arch/arm/include/asm/global_data.h
arch/arm/include/asm/imx-common/dma.h
arch/arm/include/asm/imx-common/iomux-v3.h
arch/arm/include/asm/imx-common/regs-apbh.h
arch/arm/include/asm/imx-common/regs-bch.h
arch/arm/include/asm/imx-common/regs-common.h
arch/arm/include/asm/imx-common/regs-gpmi.h
arch/arm/include/asm/system.h
arch/arm/lib/asm-offsets.c
arch/arm/lib/board.c
arch/arm/lib/cache-cp15.c
arch/arm/lib/cache.c
arch/arm/lib/crt0.S
arch/arm/lib/interrupts.c
arch/arm/lib/reset.c
arch/arm/lib/vectors.S
board/boundary/nitrogen6x/nitrogen6x.c
board/congatec/cgtqmx6eval/cgtqmx6eval.c
board/denx/m28evk/spl_boot.c
board/freescale/mx6qarm2/mx6qarm2.c
board/freescale/mx6qsabreauto/mx6qsabreauto.c
board/freescale/mx6qsabrelite/mx6qsabrelite.c [new file with mode: 0644]
board/freescale/mx6sabresd/mx6sabresd.c
board/freescale/titanium/titanium.c [new file with mode: 0644]
board/karo/common/Makefile [new file with mode: 0644]
board/karo/common/env.c [new file with mode: 0644]
board/karo/common/fdt.c [new file with mode: 0644]
board/karo/common/karo.h [new file with mode: 0644]
board/karo/common/mmc.c [new file with mode: 0644]
board/karo/common/nand.c [new file with mode: 0644]
board/karo/common/splashimage.c [new file with mode: 0644]
board/karo/dts/tx28.dts [new file with mode: 0644]
board/karo/dts/tx48.dts [new file with mode: 0644]
board/karo/dts/tx51.dts [new file with mode: 0644]
board/karo/dts/tx53.dts [new file with mode: 0644]
board/karo/dts/tx6dl.dts [new file with mode: 0644]
board/karo/dts/tx6q.dts [new file with mode: 0644]
board/karo/tx28/Kconfig [new file with mode: 0644]
board/karo/tx28/Makefile [new file with mode: 0644]
board/karo/tx28/config.mk [new file with mode: 0644]
board/karo/tx28/flash.c [new file with mode: 0644]
board/karo/tx28/spl_boot.c [new file with mode: 0644]
board/karo/tx28/tx28.c [new file with mode: 0644]
board/karo/tx28/u-boot.bd [new file with mode: 0644]
board/karo/tx48/Kconfig [new file with mode: 0644]
board/karo/tx48/Makefile [new file with mode: 0644]
board/karo/tx48/config.mk [new file with mode: 0644]
board/karo/tx48/flash.h [new file with mode: 0644]
board/karo/tx48/spl.c [new file with mode: 0644]
board/karo/tx48/tx48.c [new file with mode: 0644]
board/karo/tx48/u-boot.lds [new file with mode: 0644]
board/karo/tx51/Kconfig [new file with mode: 0644]
board/karo/tx51/Makefile [new file with mode: 0644]
board/karo/tx51/config.mk [new file with mode: 0644]
board/karo/tx51/lowlevel_init.S [new file with mode: 0644]
board/karo/tx51/tx51.c [new file with mode: 0644]
board/karo/tx51/u-boot.lds [new file with mode: 0644]
board/karo/tx53/Kconfig [new file with mode: 0644]
board/karo/tx53/Makefile [new file with mode: 0644]
board/karo/tx53/config.mk [new file with mode: 0644]
board/karo/tx53/flash.c [new file with mode: 0644]
board/karo/tx53/lowlevel_init.S [new file with mode: 0644]
board/karo/tx53/tx53.c [new file with mode: 0644]
board/karo/tx53/u-boot.lds [new file with mode: 0644]
board/karo/tx6/Kconfig [new file with mode: 0644]
board/karo/tx6/Makefile [new file with mode: 0644]
board/karo/tx6/config.mk [new file with mode: 0644]
board/karo/tx6/flash.c [new file with mode: 0644]
board/karo/tx6/lowlevel_init.S [new file with mode: 0644]
board/karo/tx6/ltc3676.c [new file with mode: 0644]
board/karo/tx6/pmic.c [new file with mode: 0644]
board/karo/tx6/pmic.h [new file with mode: 0644]
board/karo/tx6/rn5t567.c [new file with mode: 0644]
board/karo/tx6/rn5t618.c [new file with mode: 0644]
board/karo/tx6/tx6qdl.c [new file with mode: 0644]
board/karo/tx6/u-boot.lds [new file with mode: 0644]
board/wandboard/wandboard.c
common/Kconfig
common/Makefile
common/cmd_bootce.c [new file with mode: 0644]
common/cmd_gpt.c
common/cmd_mmc.c
common/cmd_mtdparts.c
common/cmd_nand.c
common/env_nand.c
common/fdt_support.c
common/lcd.c
common/spl/spl.c
common/spl/spl_nand.c
common/spl/spl_ymodem.c
common/xyzModem.c
configs/tx28-40x1_defconfig [new file with mode: 0644]
configs/tx28-40x1_noenv_defconfig [new file with mode: 0644]
configs/tx28-40x2_defconfig [new file with mode: 0644]
configs/tx28-40x2_noenv_defconfig [new file with mode: 0644]
configs/tx28-40x3_defconfig [new file with mode: 0644]
configs/tx28-40x3_noenv_defconfig [new file with mode: 0644]
configs/tx28-41x0_defconfig [new file with mode: 0644]
configs/tx28-41x0_noenv_defconfig [new file with mode: 0644]
configs/tx48_defconfig [new file with mode: 0644]
configs/tx51-8xx0_defconfig [new file with mode: 0644]
configs/tx51-8xx1_2_defconfig [new file with mode: 0644]
configs/tx53-1232_defconfig [new file with mode: 0644]
configs/tx53-x030_defconfig [new file with mode: 0644]
configs/tx53-x130_defconfig [new file with mode: 0644]
configs/tx53-x131_defconfig [new file with mode: 0644]
configs/tx6q-1020_defconfig [new file with mode: 0644]
configs/tx6q-1020_mfg_defconfig [new file with mode: 0644]
configs/tx6q-1020_noenv_defconfig [new file with mode: 0644]
configs/tx6q-10x0_defconfig [new file with mode: 0644]
configs/tx6q-10x0_mfg_defconfig [new file with mode: 0644]
configs/tx6q-10x0_noenv_defconfig [new file with mode: 0644]
configs/tx6q-11x0_defconfig [new file with mode: 0644]
configs/tx6q-11x0_mfg_defconfig [new file with mode: 0644]
configs/tx6q-11x0_noenv_defconfig [new file with mode: 0644]
configs/tx6s-8034_defconfig [new file with mode: 0644]
configs/tx6s-8034_mfg_defconfig [new file with mode: 0644]
configs/tx6s-8034_noenv_defconfig [new file with mode: 0644]
configs/tx6s-8035_defconfig [new file with mode: 0644]
configs/tx6s-8035_mfg_defconfig [new file with mode: 0644]
configs/tx6s-8035_noenv_defconfig [new file with mode: 0644]
configs/tx6u-8011_defconfig [new file with mode: 0644]
configs/tx6u-8011_mfg_defconfig [new file with mode: 0644]
configs/tx6u-8011_noenv_defconfig [new file with mode: 0644]
configs/tx6u-8012_defconfig [new file with mode: 0644]
configs/tx6u-8012_mfg_defconfig [new file with mode: 0644]
configs/tx6u-8012_noenv_defconfig [new file with mode: 0644]
configs/tx6u-8033_defconfig [new file with mode: 0644]
configs/tx6u-8033_mfg_defconfig [new file with mode: 0644]
configs/tx6u-8033_noenv_defconfig [new file with mode: 0644]
configs/tx6u-80x0_defconfig [new file with mode: 0644]
configs/tx6u-80x0_mfg_defconfig [new file with mode: 0644]
configs/tx6u-80x0_noenv_defconfig [new file with mode: 0644]
configs/tx6u-8111_defconfig [new file with mode: 0644]
configs/tx6u-8111_mfg_defconfig [new file with mode: 0644]
configs/tx6u-8111_noenv_defconfig [new file with mode: 0644]
configs/tx6u-81x0_defconfig [new file with mode: 0644]
configs/tx6u-81x0_mfg_defconfig [new file with mode: 0644]
configs/tx6u-81x0_noenv_defconfig [new file with mode: 0644]
disk/part.c
doc/README.KARO [new file with mode: 0755]
doc/README.KARO-FDT [new file with mode: 0644]
doc/README.KARO-TX28 [new file with mode: 0644]
doc/README.KARO-TX48 [new file with mode: 0644]
doc/README.KARO-TX51 [new file with mode: 0644]
doc/README.KARO-TX53 [new file with mode: 0644]
doc/README.KARO-TX6 [new file with mode: 0644]
drivers/dma/Kconfig
drivers/dma/apbh_dma.c
drivers/gpio/Makefile
drivers/gpio/am33xx_gpio.c [new file with mode: 0644]
drivers/gpio/gpio-uclass.c
drivers/gpio/gpiolib.c [new file with mode: 0644]
drivers/gpio/mxc_gpio.c
drivers/i2c/Kconfig
drivers/misc/fsl_iim.c
drivers/mmc/Kconfig
drivers/mmc/fsl_esdhc.c
drivers/mmc/mmc.c
drivers/mmc/mxsmmc.c
drivers/mmc/omap_hsmmc.c
drivers/mtd/Kconfig
drivers/mtd/nand/Kconfig
drivers/mtd/nand/mxs_nand.c
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_spl_simple.c
drivers/mtd/nand/omap_gpmc.c
drivers/net/Kconfig
drivers/net/cpsw.c
drivers/net/fec_mxc.c
drivers/net/fec_mxc.h
drivers/net/phy/Kconfig [new file with mode: 0644]
drivers/net/phy/phy.c
drivers/net/phy/smsc.c
drivers/serial/serial_imx.c
drivers/serial/serial_mxc.c
drivers/usb/host/ehci-mx6.c
drivers/video/ipu_common.c
drivers/video/ipu_disp.c
drivers/video/ipu_regs.h
drivers/video/mxc_ipuv3_fb.c
drivers/video/mxsfb.c
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/imx_watchdog.c
dts/Kconfig
include/ahci.h
include/asm-generic/gpio.h
include/configs/triton320.h [new file with mode: 0644]
include/configs/tx25.h
include/configs/tx28.h [new file with mode: 0644]
include/configs/tx48.h [new file with mode: 0644]
include/configs/tx51.h [new file with mode: 0644]
include/configs/tx53.h [new file with mode: 0644]
include/configs/tx6.h [new file with mode: 0644]
include/fsl_esdhc.h
include/ipu.h [moved from drivers/video/ipu.h with 62% similarity]
include/lcd.h
include/mxcfb.h [moved from drivers/video/mxcfb.h with 100% similarity]
include/nand.h
include/net.h
include/netdev.h
include/spl.h
include/wince.h [new file with mode: 0644]
net/Makefile
net/bootme.c [new file with mode: 0644]
net/bootp.c
net/bootp.h
net/net.c
net/net_rand.h
tools/Makefile
tools/elftosb/COPYING [new file with mode: 0644]
tools/elftosb/ReadMe.txt [new file with mode: 0644]
tools/elftosb/bdfiles/basic_test_cmd.e [new file with mode: 0644]
tools/elftosb/bdfiles/complex.bd [new file with mode: 0644]
tools/elftosb/bdfiles/habtest.bd [new file with mode: 0644]
tools/elftosb/bdfiles/simple.e [new file with mode: 0644]
tools/elftosb/bdfiles/test_cmd.e [new file with mode: 0644]
tools/elftosb/common/AESKey.cpp [new file with mode: 0644]
tools/elftosb/common/AESKey.h [new file with mode: 0644]
tools/elftosb/common/Blob.cpp [new file with mode: 0644]
tools/elftosb/common/Blob.h [new file with mode: 0644]
tools/elftosb/common/BootImage.h [new file with mode: 0644]
tools/elftosb/common/DataSource.cpp [new file with mode: 0644]
tools/elftosb/common/DataSource.h [new file with mode: 0644]
tools/elftosb/common/DataSourceImager.cpp [new file with mode: 0644]
tools/elftosb/common/DataSourceImager.h [new file with mode: 0644]
tools/elftosb/common/DataTarget.cpp [new file with mode: 0644]
tools/elftosb/common/DataTarget.h [new file with mode: 0644]
tools/elftosb/common/ELF.h [new file with mode: 0644]
tools/elftosb/common/ELFSourceFile.cpp [new file with mode: 0644]
tools/elftosb/common/ELFSourceFile.h [new file with mode: 0644]
tools/elftosb/common/EncoreBootImage.cpp [new file with mode: 0644]
tools/elftosb/common/EncoreBootImage.h [new file with mode: 0644]
tools/elftosb/common/EndianUtilities.h [new file with mode: 0644]
tools/elftosb/common/EvalContext.cpp [new file with mode: 0644]
tools/elftosb/common/EvalContext.h [new file with mode: 0644]
tools/elftosb/common/ExcludesListMatcher.cpp [new file with mode: 0644]
tools/elftosb/common/ExcludesListMatcher.h [new file with mode: 0644]
tools/elftosb/common/GHSSecInfo.cpp [new file with mode: 0644]
tools/elftosb/common/GHSSecInfo.h [new file with mode: 0644]
tools/elftosb/common/GlobMatcher.cpp [new file with mode: 0644]
tools/elftosb/common/GlobMatcher.h [new file with mode: 0644]
tools/elftosb/common/HexValues.cpp [new file with mode: 0644]
tools/elftosb/common/HexValues.h [new file with mode: 0644]
tools/elftosb/common/IVTDataSource.cpp [new file with mode: 0644]
tools/elftosb/common/IVTDataSource.h [new file with mode: 0644]
tools/elftosb/common/Logging.cpp [new file with mode: 0644]
tools/elftosb/common/Logging.h [new file with mode: 0644]
tools/elftosb/common/Operation.cpp [new file with mode: 0644]
tools/elftosb/common/Operation.h [new file with mode: 0644]
tools/elftosb/common/OptionContext.h [new file with mode: 0644]
tools/elftosb/common/OptionDictionary.cpp [new file with mode: 0644]
tools/elftosb/common/OptionDictionary.h [new file with mode: 0644]
tools/elftosb/common/OutputSection.cpp [new file with mode: 0644]
tools/elftosb/common/OutputSection.h [new file with mode: 0644]
tools/elftosb/common/Random.cpp [new file with mode: 0644]
tools/elftosb/common/Random.h [new file with mode: 0644]
tools/elftosb/common/RijndaelCBCMAC.cpp [new file with mode: 0644]
tools/elftosb/common/RijndaelCBCMAC.h [new file with mode: 0644]
tools/elftosb/common/SHA1.cpp [new file with mode: 0644]
tools/elftosb/common/SHA1.h [new file with mode: 0644]
tools/elftosb/common/SRecordSourceFile.cpp [new file with mode: 0644]
tools/elftosb/common/SRecordSourceFile.h [new file with mode: 0644]
tools/elftosb/common/SearchPath.cpp [new file with mode: 0644]
tools/elftosb/common/SearchPath.h [new file with mode: 0644]
tools/elftosb/common/SourceFile.cpp [new file with mode: 0644]
tools/elftosb/common/SourceFile.h [new file with mode: 0644]
tools/elftosb/common/StELFFile.cpp [new file with mode: 0644]
tools/elftosb/common/StELFFile.h [new file with mode: 0644]
tools/elftosb/common/StExecutableImage.cpp [new file with mode: 0644]
tools/elftosb/common/StExecutableImage.h [new file with mode: 0644]
tools/elftosb/common/StSRecordFile.cpp [new file with mode: 0644]
tools/elftosb/common/StSRecordFile.h [new file with mode: 0644]
tools/elftosb/common/StringMatcher.h [new file with mode: 0644]
tools/elftosb/common/Value.cpp [new file with mode: 0644]
tools/elftosb/common/Value.h [new file with mode: 0644]
tools/elftosb/common/Version.cpp [new file with mode: 0644]
tools/elftosb/common/Version.h [new file with mode: 0644]
tools/elftosb/common/crc.cpp [new file with mode: 0644]
tools/elftosb/common/crc.h [new file with mode: 0644]
tools/elftosb/common/format_string.cpp [new file with mode: 0644]
tools/elftosb/common/format_string.h [new file with mode: 0644]
tools/elftosb/common/int_size.h [new file with mode: 0644]
tools/elftosb/common/options.cpp [new file with mode: 0644]
tools/elftosb/common/options.h [new file with mode: 0644]
tools/elftosb/common/rijndael.cpp [new file with mode: 0644]
tools/elftosb/common/rijndael.h [new file with mode: 0644]
tools/elftosb/common/smart_ptr.h [new file with mode: 0644]
tools/elftosb/common/stdafx.cpp [new file with mode: 0644]
tools/elftosb/common/stdafx.h [new file with mode: 0644]
tools/elftosb/elftosb.ccscc [new file with mode: 0644]
tools/elftosb/elftosb.xcodeproj/creed.mode1 [new file with mode: 0644]
tools/elftosb/elftosb.xcodeproj/creed.mode1v3 [new file with mode: 0644]
tools/elftosb/elftosb.xcodeproj/creed.pbxuser [new file with mode: 0644]
tools/elftosb/elftosb.xcodeproj/project.pbxproj [new file with mode: 0644]
tools/elftosb/elftosb2/BootImageGenerator.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/BootImageGenerator.h [new file with mode: 0644]
tools/elftosb/elftosb2/ConversionController.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/ConversionController.h [new file with mode: 0644]
tools/elftosb/elftosb2/Doxyfile [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbAST.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbAST.h [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbErrors.h [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbLexer.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbLexer.h [new file with mode: 0644]
tools/elftosb/elftosb2/EncoreBootImageGenerator.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/EncoreBootImageGenerator.h [new file with mode: 0644]
tools/elftosb/elftosb2/FlexLexer.h [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb2.vcproj [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_lexer.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_lexer.l [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_parser.tab.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_parser.tab.hpp [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_parser.y [new file with mode: 0644]
tools/elftosb/encryptgpk/encryptgpk.cpp [new file with mode: 0644]
tools/elftosb/encryptgpk/encryptgpk.vcproj [new file with mode: 0644]
tools/elftosb/keygen/Doxyfile [new file with mode: 0644]
tools/elftosb/keygen/keygen.cpp [new file with mode: 0644]
tools/elftosb/keygen/keygen.vcproj [new file with mode: 0644]
tools/elftosb/makefile [new file with mode: 0644]
tools/elftosb/makefile.rules [new file with mode: 0644]
tools/elftosb/sbtool/Doxyfile [new file with mode: 0644]
tools/elftosb/sbtool/EncoreBootImageReader.cpp [new file with mode: 0644]
tools/elftosb/sbtool/EncoreBootImageReader.h [new file with mode: 0644]
tools/elftosb/sbtool/sbtool.cpp [new file with mode: 0644]
tools/elftosb/sbtool/sbtool.vcproj [new file with mode: 0644]
tools/elftosb/stdafx.h [new file with mode: 0644]
tools/elftosb/test_elftosb.bat [new file with mode: 0644]
tools/elftosb/test_elftosb.sh [new file with mode: 0755]
tools/elftosb/test_files/hello_NOR_arm [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_arm.map [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_mixed [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_mixed.map [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_thumb [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_thumb.map [new file with mode: 0644]
tools/elftosb/test_files/hostlink [new file with mode: 0644]
tools/elftosb/test_files/player_linfix.elf [new file with mode: 0644]
tools/elftosb/test_files/plugin_complex [new file with mode: 0644]
tools/elftosb/test_files/plugin_hello [new file with mode: 0644]
tools/elftosb/test_files/redboot_gcc.srec [new file with mode: 0644]
tools/elftosb/test_files/rom_nand_ldr_profile [new file with mode: 0644]
tools/elftosb/test_files/sd_player_gcc [new file with mode: 0644]
tools/elftosb/test_files/sd_player_gcc.srec [new file with mode: 0644]
tools/elftosb/test_files/test0.key [new file with mode: 0644]
tools/elftosb/winsupport/unistd.h [new file with mode: 0644]
tools/gen_eth_addr.c
tools/logos/karo.bmp [new file with mode: 0644]

index a40c277105ea65efe81a70c53715099adf6d2548..2cba50167ed64d20ba0da20a802dd46a41f33a60 100644 (file)
@@ -62,6 +62,7 @@ patches-*
 # quilt's files
 patches
 series
+.pc
 
 # gdb files
 .gdb_history
diff --git a/Kconfig b/Kconfig
index fed488fdaf94212dfce21902d2cf812a827f819e..861622664fcba27cfbf4445128ce44c8db4b9cb2 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -70,8 +70,7 @@ menu "Boot images"
 
 config SPL_BUILD
        bool
-       depends on $KCONFIG_OBJDIR="spl" || $KCONFIG_OBJDIR="tpl"
-       default y
+       default y if $KCONFIG_OBJDIR="spl" || $KCONFIG_OBJDIR="tpl"
 
 config TPL_BUILD
        bool
@@ -156,6 +155,8 @@ source "arch/Kconfig"
 
 source "common/Kconfig"
 
+source "disk/Kconfig"
+
 source "dts/Kconfig"
 
 source "net/Kconfig"
diff --git a/README b/README
index a28ff133ee057c17af79a397e44325328f82dedf..a435c8b2fa7ce054530002b7d5d8f20f197710ad 100644 (file)
--- a/README
+++ b/README
@@ -2207,6 +2207,17 @@ CBFS (Coreboot Filesystem) support
                requests. Increasing this will allow U-Boot to accept offers
                from a BOOTP client in networks with unusually high latency.
 
+- BOOTP Random transaction ID:
+               CONFIG_BOOTP_RANDOM_ID
+
+               The standard algorithm to generate a DHCP/BOOTP transaction ID
+               by using the MAC address and the current time stamp may not
+               quite unlikely produce duplicate transaction IDs from different
+               clients in the same network. This option creates a transaction
+               ID using the rand() function. Provided that the RNG has been
+               seeded well, this should guarantee unique transaction IDs
+               always.
+
 - DHCP Advanced Options:
                You can fine tune the DHCP functionality by defining
                CONFIG_BOOTP_* symbols:
index 986b4c5d81db1009110eafb2c4606c79675c03a7..0219f4ec6010a02f5d3d508e01f8e9710a23ad43 100644 (file)
@@ -258,6 +258,28 @@ config TARGET_TX25
        select CPU_ARM926EJS
        select SUPPORT_SPL
 
+config TARGET_TX28
+       bool "Support tx28"
+       select CPU_ARM926EJS
+       select SUPPORT_SPL
+
+config TARGET_TX48
+       bool "Support tx48"
+       select CPU_V7
+       select SUPPORT_SPL
+
+config TARGET_TX51
+       bool "Support tx51"
+       select CPU_V7
+
+config TARGET_TX53
+       bool "Support tx53"
+       select CPU_V7
+
+config TARGET_TX6
+       bool "Support tx6"
+       select CPU_V7
+
 config TARGET_ZMX25
        bool "Support zmx25"
        select CPU_ARM926EJS
@@ -943,6 +965,11 @@ source "board/imx31_phycore/Kconfig"
 source "board/isee/igep0033/Kconfig"
 source "board/jornada/Kconfig"
 source "board/karo/tx25/Kconfig"
+source "board/karo/tx28/Kconfig"
+source "board/karo/tx48/Kconfig"
+source "board/karo/tx51/Kconfig"
+source "board/karo/tx53/Kconfig"
+source "board/karo/tx6/Kconfig"
 source "board/kosagi/novena/Kconfig"
 source "board/logicpd/imx27lite/Kconfig"
 source "board/logicpd/imx31_litekit/Kconfig"
index 0667984b697d62845cb013ba3376cfc5ca01bbf3..51829495682045cfff5fb1d1ebac921199798534 100644 (file)
@@ -52,7 +52,7 @@ checkthumb:
 endif
 endif
 
-# Try if EABI is supported, else fall back to old API,
+# Try if EABI is supported, else fall back to old ABI,
 # i. e. for example:
 # - with ELDK 4.2 (EABI supported), use:
 #      -mabi=aapcs-linux
index a90ce3047bd27f2f100512ce6239073ac6c92fa9..d1d2a176f673448321a9edb5869d166b3fb54d85 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <lcd.h>
 #include <asm/system.h>
 
 static void cache_flush(void);
@@ -30,6 +31,14 @@ int cleanup_before_linux (void)
 
        disable_interrupts ();
 
+#ifdef CONFIG_LCD
+       {
+               /* switch off LCD panel */
+               lcd_panel_disable();
+               /* disable LCD controller */
+               lcd_disable();
+       }
+#endif
 
        /* turn off I/D-cache */
        icache_disable();
index e9d8800f8c1b30f26d3598bdbb18d14732949638..4d0cc04583324eab342cf6373a76bbc57ef6bd4f 100644 (file)
 #define MXC_SSPCLK_MAX MXC_SSPCLK3
 #endif
 
-static uint32_t mxs_get_pclk(void)
+static struct mxs_clkctrl_regs *clkctrl_regs = (void *)MXS_CLKCTRL_BASE;
+
+static uint32_t get_frac_clk(uint32_t refclk, uint32_t div, uint32_t _mask)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+       uint32_t mask = (_mask + 1) >> 1;
+       uint32_t acc = div;
+       int period = 0;
+       int mult = 0;
+
+       if (div & mask)
+               return 0;
+
+       do {
+               acc += div;
+               if (acc & mask) {
+                       acc &= ~mask;
+                       mult++;
+               }
+               period++;
+       } while (acc != div);
 
+       return refclk * mult / period;
+}
+
+static uint32_t mxs_get_pclk(void)
+{
        uint32_t clkctrl, clkseq, div;
        uint8_t clkfrac, frac;
 
        clkctrl = readl(&clkctrl_regs->hw_clkctrl_cpu);
 
-       /* No support of fractional divider calculation */
+       div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK;
+       clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]);
+       frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
+       clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
+
        if (clkctrl &
                (CLKCTRL_CPU_DIV_XTAL_FRAC_EN | CLKCTRL_CPU_DIV_CPU_FRAC_EN)) {
-               return 0;
+               uint32_t refclk, mask;
+
+               if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) {
+                       refclk = XTAL_FREQ_MHZ;
+                       mask = CLKCTRL_CPU_DIV_XTAL_MASK >>
+                               CLKCTRL_CPU_DIV_XTAL_OFFSET;
+                       div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >>
+                               CLKCTRL_CPU_DIV_XTAL_OFFSET;
+               } else {
+                       refclk = PLL_FREQ_MHZ * PLL_FREQ_COEF / frac;
+                       mask = CLKCTRL_CPU_DIV_CPU_MASK;
+               }
+               return get_frac_clk(refclk, div, mask);
        }
 
-       clkseq = readl(&clkctrl_regs->hw_clkctrl_clkseq);
-
        /* XTAL Path */
        if (clkseq & CLKCTRL_CLKSEQ_BYPASS_CPU) {
                div = (clkctrl & CLKCTRL_CPU_DIV_XTAL_MASK) >>
@@ -60,35 +95,26 @@ static uint32_t mxs_get_pclk(void)
        }
 
        /* REF Path */
-       clkfrac = readb(&clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU]);
-       frac = clkfrac & CLKCTRL_FRAC_FRAC_MASK;
-       div = clkctrl & CLKCTRL_CPU_DIV_CPU_MASK;
        return (PLL_FREQ_MHZ * PLL_FREQ_COEF / frac) / div;
 }
 
 static uint32_t mxs_get_hclk(void)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
-
        uint32_t div;
        uint32_t clkctrl;
+       uint32_t refclk = mxs_get_pclk();
 
        clkctrl = readl(&clkctrl_regs->hw_clkctrl_hbus);
+       div = clkctrl & CLKCTRL_HBUS_DIV_MASK;
 
-       /* No support of fractional divider calculation */
        if (clkctrl & CLKCTRL_HBUS_DIV_FRAC_EN)
-               return 0;
+               return get_frac_clk(refclk, div, CLKCTRL_HBUS_DIV_MASK);
 
-       div = clkctrl & CLKCTRL_HBUS_DIV_MASK;
-       return mxs_get_pclk() / div;
+       return refclk / div;
 }
 
 static uint32_t mxs_get_emiclk(void)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
-
        uint32_t clkctrl, clkseq, div;
        uint8_t clkfrac, frac;
 
@@ -111,8 +137,6 @@ static uint32_t mxs_get_emiclk(void)
 
 static uint32_t mxs_get_gpmiclk(void)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
 #if defined(CONFIG_MX23)
        uint8_t *reg =
                &clkctrl_regs->hw_clkctrl_frac0[CLKCTRL_FRAC0_CPU];
@@ -144,8 +168,6 @@ static uint32_t mxs_get_gpmiclk(void)
  */
 void mxs_set_ioclk(enum mxs_ioclock io, uint32_t freq)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
        uint32_t div;
        int io_reg;
 
@@ -177,14 +199,14 @@ void mxs_set_ioclk(enum mxs_ioclock io, uint32_t freq)
  */
 static uint32_t mxs_get_ioclk(enum mxs_ioclock io)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
        uint8_t ret;
        int io_reg;
 
-       if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1))
+       if ((io < MXC_IOCLK0) || (io > MXC_IOCLK1)) {
+               printf("%s: IO clock selector %u out of range %u..%u\n",
+                       __func__, io, MXC_IOCLK0, MXC_IOCLK1);
                return 0;
-
+       }
        io_reg = CLKCTRL_FRAC0_IO0 - io;        /* Register order is reversed */
 
        ret = readb(&clkctrl_regs->hw_clkctrl_frac0[io_reg]) &
@@ -198,8 +220,6 @@ static uint32_t mxs_get_ioclk(enum mxs_ioclock io)
  */
 void mxs_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
        uint32_t clk, clkreg;
 
        if (ssp > MXC_SSPCLK_MAX)
@@ -242,9 +262,7 @@ void mxs_set_sspclk(enum mxs_sspclock ssp, uint32_t freq, int xtal)
  */
 static uint32_t mxs_get_sspclk(enum mxs_sspclock ssp)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
-       uint32_t clkreg;
+       uint32_t *clkreg;
        uint32_t clk, tmp;
 
        if (ssp > MXC_SSPCLK_MAX)
@@ -254,11 +272,10 @@ static uint32_t mxs_get_sspclk(enum mxs_sspclock ssp)
        if (tmp & (CLKCTRL_CLKSEQ_BYPASS_SSP0 << ssp))
                return XTAL_FREQ_KHZ;
 
-       clkreg = (uint32_t)(&clkctrl_regs->hw_clkctrl_ssp0) +
-                       (ssp * sizeof(struct mxs_register_32));
+       clkreg = &clkctrl_regs->hw_clkctrl_ssp0 +
+                       ssp * sizeof(struct mxs_register_32);
 
        tmp = readl(clkreg) & CLKCTRL_SSP_DIV_MASK;
-
        if (tmp == 0)
                return 0;
 
@@ -311,8 +328,6 @@ void mxs_set_ssp_busclock(unsigned int bus, uint32_t freq)
 
 void mxs_set_lcdclk(uint32_t freq)
 {
-       struct mxs_clkctrl_regs *clkctrl_regs =
-               (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
        uint32_t fp, x, k_rest, k_best, x_best, tk;
        int32_t k_best_l = 999, k_best_t = 0, x_best_l = 0xff, x_best_t = 0xff;
 
@@ -391,17 +406,39 @@ void mxs_set_lcdclk(uint32_t freq)
        writeb(CLKCTRL_FRAC_CLKGATE,
                &clkctrl_regs->hw_clkctrl_frac1_clr[CLKCTRL_FRAC1_PIX]);
 
-       writel(CLKCTRL_DIS_LCDIF_CLKGATE,
-               &clkctrl_regs->hw_clkctrl_lcdif_set);
-       clrsetbits_le32(&clkctrl_regs->hw_clkctrl_lcdif,
-                       CLKCTRL_DIS_LCDIF_DIV_MASK | CLKCTRL_DIS_LCDIF_CLKGATE,
-                       k_best << CLKCTRL_DIS_LCDIF_DIV_OFFSET);
+       /* The i.MX28 Ref. Manual states:
+        * CLK_DIS_LCDIF Gate. If set to 1, CLK_DIS_LCDIF is gated off.
+        * 0: CLK_DIS_LCDIF is not gated.
+        * When this bit is modified, or when it is high,
+        * the DIV field should not change its value.
+        * The DIV field can change ONLY when this clock gate bit field is low.
+        * Note: This register does not have set/clear/toggle functionality!
+        */
+       /* clear CLKCTRL_DIS_LCDIF_CLKGATE */
+       writel(0, &clkctrl_regs->hw_clkctrl_lcdif);
+       writel(k_best << CLKCTRL_DIS_LCDIF_DIV_OFFSET,
+               &clkctrl_regs->hw_clkctrl_lcdif);
 
        while (readl(&clkctrl_regs->hw_clkctrl_lcdif) & CLKCTRL_DIS_LCDIF_BUSY)
                ;
 #endif
 }
 
+static uint32_t mxs_get_xbus_clk(void)
+{
+       uint32_t div;
+       uint32_t clkctrl;
+       uint32_t refclk = mxs_get_pclk();
+
+       clkctrl = readl(&clkctrl_regs->hw_clkctrl_xbus);
+       div = clkctrl & CLKCTRL_XBUS_DIV_MASK;
+
+       if (clkctrl & CLKCTRL_XBUS_DIV_FRAC_EN)
+               return get_frac_clk(refclk, div, CLKCTRL_XBUS_DIV_MASK);
+
+       return refclk / div;
+}
+
 uint32_t mxc_get_clock(enum mxc_clock clk)
 {
        switch (clk) {
@@ -430,6 +467,10 @@ uint32_t mxc_get_clock(enum mxc_clock clk)
        case MXC_SSP3_CLK:
                return mxs_get_sspclk(MXC_SSPCLK3);
 #endif
+       case MXC_XBUS_CLK:
+               return mxs_get_xbus_clk() * 1000000;
+       default:
+               printf("Invalid clock selector %u\n", clk);
        }
 
        return 0;
index ef130aea426975babb926a48d0da0e863ec65638..f3c1575a36897bff3c6913be37309d70c1db120f 100644 (file)
@@ -26,6 +26,31 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Lowlevel init isn't used on i.MX28, so just have a dummy here */
 inline void lowlevel_init(void) {}
 
+#define BOOT_CAUSE_MASK                (RTC_PERSISTENT0_EXTERNAL_RESET |       \
+                               RTC_PERSISTENT0_ALARM_WAKE |            \
+                               RTC_PERSISTENT0_THERMAL_RESET)
+
+static int wait_rtc_stat(u32 mask)
+{
+       int timeout = 5000;
+       u32 val;
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
+       u32 old_val = readl(&rtc_regs->hw_rtc_stat);
+
+       debug("stat=%x\n", old_val);
+
+       while ((val = readl(&rtc_regs->hw_rtc_stat)) & mask) {
+               if (val != old_val) {
+                       old_val = val;
+                       debug("stat: %x -> %x\n", old_val, val);
+               }
+               udelay(1);
+               if (timeout-- < 0)
+                       break;
+       }
+       return !!(readl(&rtc_regs->hw_rtc_stat) & mask);
+}
+
 void reset_cpu(ulong ignored) __attribute__((noreturn));
 
 void reset_cpu(ulong ignored)
@@ -34,6 +59,7 @@ void reset_cpu(ulong ignored)
                (struct mxs_rtc_regs *)MXS_RTC_BASE;
        struct mxs_lcdif_regs *lcdif_regs =
                (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
+       u32 reg;
 
        /*
         * Shut down the LCD controller as it interferes with BootROM boot mode
@@ -41,7 +67,13 @@ void reset_cpu(ulong ignored)
         */
        writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr);
 
-       /* Wait 1 uS before doing the actual watchdog reset */
+       reg = readl(&rtc_regs->hw_rtc_persistent0);
+       if (reg & BOOT_CAUSE_MASK) {
+               writel(reg & ~BOOT_CAUSE_MASK, &rtc_regs->hw_rtc_persistent0);
+               wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0);
+       }
+
+       /* Wait 1 mS before doing the actual watchdog reset */
        writel(1, &rtc_regs->hw_rtc_watchdog);
        writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set);
 
@@ -77,17 +109,21 @@ void enable_caches(void)
 void mx28_fixup_vt(uint32_t start_addr)
 {
        /* ldr pc, [pc, #0x18] */
-       const uint32_t ldr_pc = 0xe59ff018;
        /* Jumptable location is 0x0 */
-       uint32_t *vt = (uint32_t *)0x0;
-       int i;
+       uint32_t *vt = (uint32_t *)0x20;
+       uint32_t cr = get_cr();
 
+<<<<<<< HEAD
        for (i = 0; i < 8; i++) {
                /* cppcheck-suppress nullPointer */
                vt[i] = ldr_pc;
                /* cppcheck-suppress nullPointer */
                vt[i + 8] = start_addr + (4 * i);
        }
+=======
+       memcpy(vt, (void *)start_addr + 0x20, 32);
+       set_cr(cr & ~CR_V);
+>>>>>>> karo-tx-uboot
 }
 
 #ifdef CONFIG_ARCH_MISC_INIT
@@ -98,6 +134,7 @@ int arch_misc_init(void)
 }
 #endif
 
+#ifdef CONFIG_ARCH_CPU_INIT
 int arch_cpu_init(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
@@ -131,6 +168,7 @@ int arch_cpu_init(void)
 
        return 0;
 }
+#endif
 
 #if defined(CONFIG_DISPLAY_CPUINFO)
 static const char *get_cpu_type(void)
@@ -196,12 +234,21 @@ int print_cpuinfo(void)
 }
 #endif
 
+#define pr_clk(n, c) {                                         \
+       unsigned long clk = c;  \
+       printf("%-5s  %3lu.%03lu MHz\n", #n ":", clk / 1000000, \
+               clk / 1000 % 1000);                             \
+}
+
 int do_mx28_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
-       printf("CPU:   %3d MHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000000);
-       printf("BUS:   %3d MHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000000);
-       printf("EMI:   %3d MHz\n", mxc_get_clock(MXC_EMI_CLK));
-       printf("GPMI:  %3d MHz\n", mxc_get_clock(MXC_GPMI_CLK) / 1000000);
+       pr_clk(CPU, mxc_get_clock(MXC_ARM_CLK));
+       pr_clk(APBH, mxc_get_clock(MXC_AHB_CLK));
+       pr_clk(APBX, mxc_get_clock(MXC_XBUS_CLK));
+       pr_clk(IO0, mxc_get_clock(MXC_IO0_CLK) * 1000);
+       pr_clk(IO1, mxc_get_clock(MXC_IO1_CLK) * 1000);
+       pr_clk(EMI, mxc_get_clock(MXC_EMI_CLK) * 1000000);
+       pr_clk(GPMI, mxc_get_clock(MXC_GPMI_CLK));
        return 0;
 }
 
@@ -225,13 +272,17 @@ int cpu_eth_init(bd_t *bis)
 
        udelay(10);
 
+       /*
+        * Enable pad output; must be done BEFORE enabling PLL
+        * according to i.MX28 Ref. Manual Rev. 1, 2010 p. 883
+        */
+       setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
+
        /* Gate on ENET PLL */
        writel(CLKCTRL_PLL2CTRL0_CLKGATE,
                &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
 
-       /* Enable pad output */
-       setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
-
+       udelay(6000);
        return 0;
 }
 #endif
index d29b9aaf3da576889bfb02620e8e7aeb106b8db7..49d50196e005874007e652f80ca9c5c11f7aee76 100644 (file)
@@ -29,15 +29,18 @@ static bd_t bdata __section(".data");
  * takes a few seconds to roll. The boot doesn't take that long, so to keep the
  * code simple, it doesn't take rolling into consideration.
  */
+/*
+ * There's nothing to be taken into consideration for the rollover.
+ * Two's complement arithmetic used correctly does all that's needed
+ * automagically.
+ */
 void early_delay(int delay)
 {
        struct mxs_digctl_regs *digctl_regs =
                (struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
+       u32 start = readl(&digctl_regs->hw_digctl_microseconds);
 
-       uint32_t st = readl(&digctl_regs->hw_digctl_microseconds);
-       st += delay;
-       while (st > readl(&digctl_regs->hw_digctl_microseconds))
-               ;
+       while (readl(&digctl_regs->hw_digctl_microseconds) - start < delay);
 }
 
 #define        MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
@@ -158,7 +161,7 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
        mxs_power_wait_pswitch();
 }
 
-/* Support aparatus */
+/* Support apparatus */
 inline void board_init_f(unsigned long bootflag)
 {
        for (;;)
index 97ef67d8c5843b06fcd6c7d903cd3d4cb21d976b..d5842e68133e880ba142c65b45512f9912827a54 100644 (file)
@@ -158,18 +158,17 @@ static void mxs_mem_init_clock(void)
        writeb(CLKCTRL_FRAC_CLKGATE,
                &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]);
 
-       early_delay(11000);
 
        /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */
        writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
                (1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
                &clkctrl_regs->hw_clkctrl_emi);
+       while (readl(&clkctrl_regs->hw_clkctrl_emi) & CLKCTRL_EMI_BUSY_REF_EMI)
+               ;
 
        /* Unbypass EMI */
        writel(CLKCTRL_CLKSEQ_BYPASS_EMI,
                &clkctrl_regs->hw_clkctrl_clkseq_clr);
-
-       early_delay(10000);
 }
 
 static void mxs_mem_setup_cpu_and_hbus(void)
@@ -187,49 +186,51 @@ static void mxs_mem_setup_cpu_and_hbus(void)
                &clkctrl_regs->hw_clkctrl_clkseq_set);
 
        /* HBUS = 151MHz */
-       writel(CLKCTRL_HBUS_DIV_MASK, &clkctrl_regs->hw_clkctrl_hbus_set);
-       writel(((~3) << CLKCTRL_HBUS_DIV_OFFSET) & CLKCTRL_HBUS_DIV_MASK,
-               &clkctrl_regs->hw_clkctrl_hbus_clr);
-
-       early_delay(10000);
+       clrsetbits_le32(&clkctrl_regs->hw_clkctrl_hbus,
+                       CLKCTRL_HBUS_DIV_MASK,
+                       3 << CLKCTRL_HBUS_DIV_OFFSET);
+       while (readl(&clkctrl_regs->hw_clkctrl_hbus) & CLKCTRL_HBUS_ASM_BUSY)
+               ;
 
        /* CPU clock divider = 1 */
        clrsetbits_le32(&clkctrl_regs->hw_clkctrl_cpu,
-                       CLKCTRL_CPU_DIV_CPU_MASK, 1);
+                       CLKCTRL_CPU_DIV_CPU_MASK,
+                       1 << CLKCTRL_CPU_DIV_CPU_OFFSET);
+       while (readl(&clkctrl_regs->hw_clkctrl_cpu) & CLKCTRL_CPU_BUSY_REF_CPU)
+               ;
 
        /* Disable CPU bypass */
        writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
                &clkctrl_regs->hw_clkctrl_clkseq_clr);
-
-       early_delay(15000);
 }
 
-static void mxs_mem_setup_vdda(void)
+void data_abort_memdetect_handler(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
-       writel((0xc << POWER_VDDACTRL_TRG_OFFSET) |
-               (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) |
-               POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW,
-               &power_regs->hw_power_vddactrl);
+       asm volatile("subs pc, lr, #4");
 }
 
 uint32_t mxs_mem_get_size(void)
 {
        uint32_t sz, da;
        uint32_t *vt = (uint32_t *)0x20;
-       /* The following is "subs pc, r14, #4", used as return from DABT. */
-       const uint32_t data_abort_memdetect_handler = 0xe25ef004;
+       unsigned long cr;
+
+       /* move vector table to low memory */
+       asm volatile(
+               "mrc p15, 0, %0, c1, c0, 0\n"
+               "bic r7, %0, #(1 << 13)\n"
+               "mcr p15, 0, r7, c1, c0, 0\n"
+               : "=r"(cr) : : "r7");
 
        /* Replace the DABT handler. */
        da = vt[4];
-       vt[4] = data_abort_memdetect_handler;
+       vt[4] = (uint32_t)data_abort_memdetect_handler;
 
        sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
 
        /* Restore the old DABT handler. */
        vt[4] = da;
+       asm volatile("mcr p15, 0, %0, c1, c0, 0\n" : : "r"(cr));
 
        return sz;
 }
@@ -328,15 +329,11 @@ void mxs_mem_init(void)
 
        mxs_mem_init_clock();
 
-       mxs_mem_setup_vdda();
-
 #if defined(CONFIG_MX23)
        mx23_mem_init();
 #elif defined(CONFIG_MX28)
        mx28_mem_init();
 #endif
 
-       early_delay(10000);
-
        mxs_mem_setup_cpu_and_hbus();
 }
index 1c54ab7de3bfc3726b1c823e47500a462607b1a4..161a1e157ac5ae369f3e64e2927757e4e72432b0 100644 (file)
 
 #include "mxs_init.h"
 
+#ifdef CONFIG_SYS_SPL_VDDD_VAL
+#define VDDD_VAL       CONFIG_SYS_SPL_VDDD_VAL
+#else
+#define VDDD_VAL       1350
+#endif
+#ifdef CONFIG_SYS_SPL_VDDIO_VAL
+#define VDDIO_VAL      CONFIG_SYS_SPL_VDDIO_VAL
+#else
+#define VDDIO_VAL      3300
+#endif
+#ifdef CONFIG_SYS_SPL_VDDA_VAL
+#define VDDA_VAL       CONFIG_SYS_SPL_VDDA_VAL
+#else
+#define VDDA_VAL       1800
+#endif
+#ifdef CONFIG_SYS_SPL_VDDMEM_VAL
+#define VDDMEM_VAL     CONFIG_SYS_SPL_VDDMEM_VAL
+#else
+#define VDDMEM_VAL     1700
+#endif
+
+#ifdef CONFIG_SYS_SPL_VDDD_BO_VAL
+#define VDDD_BO_VAL    CONFIG_SYS_SPL_VDDD_BO_VAL
+#else
+#define VDDD_BO_VAL    150
+#endif
+#ifdef CONFIG_SYS_SPL_VDDIO_BO_VAL
+#define VDDIO_BO_VAL   CONFIG_SYS_SPL_VDDIO_BO_VAL
+#else
+#define VDDIO_BO_VAL   150
+#endif
+#ifdef CONFIG_SYS_SPL_VDDA_BO_VAL
+#define VDDA_BO_VAL    CONFIG_SYS_SPL_VDDA_BO_VAL
+#else
+#define VDDA_BO_VAL    175
+#endif
+#ifdef CONFIG_SYS_SPL_VDDMEM_BO_VAL
+#define VDDMEM_BO_VAL  CONFIG_SYS_SPL_VDDMEM_BO_VAL
+#else
+#define VDDMEM_BO_VAL  25
+#endif
+
+#ifdef CONFIG_SYS_SPL_BATT_BO_LEVEL
+#if CONFIG_SYS_SPL_BATT_BO_LEVEL < 2400 || CONFIG_SYS_SPL_BATT_BO_LEVEL > 3640
+#error CONFIG_SYS_SPL_BATT_BO_LEVEL out of range
+#endif
+#define BATT_BO_VAL    (((CONFIG_SYS_SPL_BATT_BO_LEVEL) - 2400) / 40)
+#else
+/* Brownout default at 3V */
+#define BATT_BO_VAL    ((3000 - 2400) / 40)
+#endif
+
+#ifdef CONFIG_SYS_SPL_FIXED_BATT_SUPPLY
+static const int fixed_batt_supply = 1;
+#else
+static const int fixed_batt_supply;
+#endif
+
+static struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
+
 /**
  * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL
  *
@@ -50,41 +110,51 @@ static void mxs_power_clock2pll(void)
                        CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
 
+static int mxs_power_wait_rtc_stat(u32 mask)
+{
+       int timeout = 5000; /* 3 ms according to i.MX28 Ref. Manual */
+       u32 val;
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
+
+       while ((val = readl(&rtc_regs->hw_rtc_stat)) & mask) {
+               early_delay(1);
+               if (timeout-- < 0)
+                       break;
+       }
+       return !!(readl(&rtc_regs->hw_rtc_stat) & mask);
+}
+
 /**
  * mxs_power_set_auto_restart() - Set the auto-restart bit
  *
  * This function ungates the RTC block and sets the AUTO_RESTART
  * bit to work around a design bug on MX28EVK Rev. A .
  */
-
-static void mxs_power_set_auto_restart(void)
+static int mxs_power_set_auto_restart(int on)
 {
-       struct mxs_rtc_regs *rtc_regs =
-               (struct mxs_rtc_regs *)MXS_RTC_BASE;
-
-       writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
-               ;
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
 
-       writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
-               ;
+       if (mxs_power_wait_rtc_stat(RTC_STAT_STALE_REGS_PERSISTENT0))
+               return 1;
 
        /* Do nothing if flag already set */
        if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
-               return;
+               return 0;
 
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
-               ;
+       if ((!(readl(&rtc_regs->hw_rtc_persistent0) &
+                               RTC_PERSISTENT0_AUTO_RESTART) ^ !on) == 0)
+               return 0;
 
-       setbits_le32(&rtc_regs->hw_rtc_persistent0,
-                       RTC_PERSISTENT0_AUTO_RESTART);
-       writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
-       writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
-               ;
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
-               ;
+       if (mxs_power_wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0))
+               return 1;
+
+       clrsetbits_le32(&rtc_regs->hw_rtc_persistent0,
+                       !on * RTC_PERSISTENT0_AUTO_RESTART,
+                       !!on * RTC_PERSISTENT0_AUTO_RESTART);
+       if (mxs_power_wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0))
+               return 1;
+
+       return 0;
 }
 
 /**
@@ -97,9 +167,6 @@ static void mxs_power_set_auto_restart(void)
  */
 static void mxs_power_set_linreg(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /* Set linear regulator 25mV below switching converter */
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                        POWER_VDDDCTRL_LINREG_OFFSET_MASK,
@@ -121,9 +188,8 @@ static void mxs_power_set_linreg(void)
  */
 static int mxs_get_batt_volt(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t volt = readl(&power_regs->hw_power_battmonitor);
+
        volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
        volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
        volt *= 8;
@@ -150,8 +216,6 @@ static int mxs_is_batt_ready(void)
  */
 static int mxs_is_batt_good(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t volt = mxs_get_batt_volt();
 
        if ((volt >= 2400) && (volt <= 4300))
@@ -199,9 +263,6 @@ static int mxs_is_batt_good(void)
  */
 static void mxs_power_setup_5v_detect(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /* Start 5V detection */
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                        POWER_5VCTRL_VBUSVALID_TRSH_MASK,
@@ -217,9 +278,6 @@ static void mxs_power_setup_5v_detect(void)
  */
 static void mxs_src_power_init(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /* Improve efficieny and reduce transient ripple */
        writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
                POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
@@ -228,8 +286,14 @@ static void mxs_src_power_init(void)
                        POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
                        0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
 
-       setbits_le32(&power_regs->hw_power_battmonitor,
+       if (!fixed_batt_supply) {
+               /* FIXME: This requires the LRADC to be set up! */
+               setbits_le32(&power_regs->hw_power_battmonitor,
                        POWER_BATTMONITOR_EN_BATADJ);
+       } else {
+               clrbits_le32(&power_regs->hw_power_battmonitor,
+                       POWER_BATTMONITOR_EN_BATADJ);
+       }
 
        /* Increase the RCSCALE level for quick DCDC response to dynamic load */
        clrsetbits_le32(&power_regs->hw_power_loopctrl,
@@ -240,10 +304,12 @@ static void mxs_src_power_init(void)
        clrsetbits_le32(&power_regs->hw_power_minpwr,
                        POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
 
-       /* 5V to battery handoff ... FIXME */
-       setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
-       early_delay(30);
-       clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+       if (!fixed_batt_supply) {
+               /* 5V to battery handoff ... FIXME */
+               setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+               early_delay(30);
+               clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+       }
 }
 
 /**
@@ -254,9 +320,6 @@ static void mxs_src_power_init(void)
  */
 static void mxs_power_init_4p2_params(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /* Setup 4P2 parameters */
        clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
                POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
@@ -284,8 +347,6 @@ static void mxs_power_init_4p2_params(void)
  */
 static void mxs_enable_4p2_dcdc_input(int xfer)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
        uint32_t prev_5v_brnout, prev_5v_droop;
 
@@ -386,8 +447,6 @@ static void mxs_enable_4p2_dcdc_input(int xfer)
  */
 static void mxs_power_init_4p2_regulator(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, tmp2;
 
        setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
@@ -476,9 +535,6 @@ static void mxs_power_init_4p2_regulator(void)
  */
 static void mxs_power_init_dcdc_4p2_source(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        if (!(readl(&power_regs->hw_power_dcdc4p2) &
                POWER_DCDC4P2_ENABLE_DCDC)) {
                hang();
@@ -504,8 +560,6 @@ static void mxs_power_init_dcdc_4p2_source(void)
  */
 static void mxs_power_enable_4p2(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t vdddctrl, vddactrl, vddioctrl;
        uint32_t tmp;
 
@@ -571,9 +625,6 @@ static void mxs_power_enable_4p2(void)
  */
 static void mxs_boot_valid_5v(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /*
         * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
         * disconnect event. FIXME
@@ -599,8 +650,6 @@ static void mxs_boot_valid_5v(void)
  */
 static void mxs_powerdown(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
        writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
                &power_regs->hw_power_reset);
@@ -614,9 +663,6 @@ static void mxs_powerdown(void)
  */
 static void mxs_batt_boot(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
 
@@ -668,8 +714,6 @@ static void mxs_batt_boot(void)
  */
 static void mxs_handle_5v_conflict(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
        setbits_le32(&power_regs->hw_power_vddioctrl,
@@ -710,9 +754,6 @@ static void mxs_handle_5v_conflict(void)
  */
 static void mxs_5v_boot(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /*
         * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
         * but their implementation always returns 1 so we omit it here.
@@ -739,13 +780,40 @@ static void mxs_5v_boot(void)
  */
 static void mxs_init_batt_bo(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
+       writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
+
+       setbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_PWDN_5VBRNOUT |
+               POWER_5VCTRL_ENABLE_DCDC |
+               POWER_5VCTRL_ILIMIT_EQ_ZERO |
+               POWER_5VCTRL_PWDN_5VBRNOUT |
+               POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
+
+       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
+
+       clrbits_le32(&power_regs->hw_power_vdddctrl,
+               POWER_VDDDCTRL_DISABLE_FET |
+               POWER_VDDDCTRL_ENABLE_LINREG |
+               POWER_VDDDCTRL_DISABLE_STEPPING);
+
+       clrbits_le32(&power_regs->hw_power_vddactrl,
+               POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
+               POWER_VDDACTRL_DISABLE_STEPPING);
+
+       clrbits_le32(&power_regs->hw_power_vddioctrl,
+               POWER_VDDIOCTRL_DISABLE_FET |
+               POWER_VDDIOCTRL_DISABLE_STEPPING);
 
-       /* Brownout at 3V */
+       /* Stop 5V detection */
+       writel(POWER_5VCTRL_PWRUP_VBUS_CMPS,
+               &power_regs->hw_power_5vctrl_clr);
+}
+
+static void mxs_init_batt_bo(void)
+{
        clrsetbits_le32(&power_regs->hw_power_battmonitor,
                POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
-               15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
+               BATT_BO_VAL << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
 
        writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
        writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
@@ -759,9 +827,6 @@ static void mxs_init_batt_bo(void)
  */
 static void mxs_switch_vddd_to_dcdc_source(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                POWER_VDDDCTRL_LINREG_OFFSET_MASK,
                POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
@@ -782,33 +847,32 @@ static void mxs_switch_vddd_to_dcdc_source(void)
  */
 static void mxs_power_configure_power_source(void)
 {
-       int batt_ready, batt_good;
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        struct mxs_lradc_regs *lradc_regs =
                (struct mxs_lradc_regs *)MXS_LRADC_BASE;
 
        mxs_src_power_init();
 
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
-               batt_ready = mxs_is_batt_ready();
-               if (batt_ready) {
-                       /* 5V source detected, good battery detected. */
-                       mxs_batt_boot();
-               } else {
-                       batt_good = mxs_is_batt_good();
-                       if (!batt_good) {
-                               /* 5V source detected, bad battery detected. */
-                               writel(LRADC_CONVERSION_AUTOMATIC,
-                                       &lradc_regs->hw_lradc_conversion_clr);
-                               clrbits_le32(&power_regs->hw_power_battmonitor,
-                                       POWER_BATTMONITOR_BATT_VAL_MASK);
+       if (!fixed_batt_supply) {
+               if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+                       if (mxs_is_batt_ready()) {
+                               /* 5V source detected, good battery detected. */
+                               mxs_batt_boot();
+                       } else {
+                               if (!mxs_is_batt_good()) {
+                                       /* 5V source detected, bad battery detected. */
+                                       writel(LRADC_CONVERSION_AUTOMATIC,
+                                               &lradc_regs->hw_lradc_conversion_clr);
+                                       clrbits_le32(&power_regs->hw_power_battmonitor,
+                                               POWER_BATTMONITOR_BATT_VAL_MASK);
+                               }
+                               mxs_5v_boot();
                        }
-                       mxs_5v_boot();
+               } else {
+                       /* 5V not detected, booting from battery. */
+                       mxs_batt_boot();
                }
        } else {
-               /* 5V not detected, booting from battery. */
-               mxs_batt_boot();
+               mxs_fixed_batt_boot();
        }
 
        mxs_power_clock2pll();
@@ -835,9 +899,6 @@ static void mxs_power_configure_power_source(void)
  */
 static void mxs_enable_output_rail_protection(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 
@@ -860,11 +921,12 @@ static void mxs_enable_output_rail_protection(void)
  */
 static int mxs_get_vddio_power_source_off(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+       if ((readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) &&
+               !(readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ILIMIT_EQ_ZERO)) {
+
                tmp = readl(&power_regs->hw_power_vddioctrl);
                if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
                        if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
@@ -883,7 +945,6 @@ static int mxs_get_vddio_power_source_off(void)
        }
 
        return 0;
-
 }
 
 /**
@@ -895,8 +956,6 @@ static int mxs_get_vddio_power_source_off(void)
  */
 static int mxs_get_vddd_power_source_off(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
        tmp = readl(&power_regs->hw_power_vdddctrl);
@@ -924,10 +983,40 @@ static int mxs_get_vddd_power_source_off(void)
        return 0;
 }
 
+static int mxs_get_vdda_power_source_off(void)
+{
+       uint32_t tmp;
+
+       tmp = readl(&power_regs->hw_power_vddactrl);
+       if (tmp & POWER_VDDACTRL_DISABLE_FET) {
+               if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDACTRL_LINREG_OFFSET_0STEPS) {
+                       return 1;
+               }
+       }
+
+       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+               if (!(readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ENABLE_DCDC)) {
+                       return 1;
+               }
+       }
+
+       if (!(tmp & POWER_VDDACTRL_ENABLE_LINREG)) {
+               if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 struct mxs_vddx_cfg {
        uint32_t                *reg;
        uint8_t                 step_mV;
        uint16_t                lowest_mV;
+       uint16_t                highest_mV;
        int                     (*powered_by_linreg)(void);
        uint32_t                trg_mask;
        uint32_t                bo_irq;
@@ -936,15 +1025,17 @@ struct mxs_vddx_cfg {
        uint32_t                bo_offset_offset;
 };
 
+#define POWER_REG(n)           &((struct mxs_power_regs *)MXS_POWER_BASE)->n
+
 static const struct mxs_vddx_cfg mxs_vddio_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vddioctrl),
+       .reg                    = POWER_REG(hw_power_vddioctrl),
 #if defined(CONFIG_MX23)
        .step_mV                = 25,
 #else
        .step_mV                = 50,
 #endif
        .lowest_mV              = 2800,
+       .highest_mV             = 3600,
        .powered_by_linreg      = mxs_get_vddio_power_source_off,
        .trg_mask               = POWER_VDDIOCTRL_TRG_MASK,
        .bo_irq                 = POWER_CTRL_VDDIO_BO_IRQ,
@@ -954,10 +1045,10 @@ static const struct mxs_vddx_cfg mxs_vddio_cfg = {
 };
 
 static const struct mxs_vddx_cfg mxs_vddd_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vdddctrl),
+       .reg                    = POWER_REG(hw_power_vdddctrl),
        .step_mV                = 25,
        .lowest_mV              = 800,
+       .highest_mV             = 1575,
        .powered_by_linreg      = mxs_get_vddd_power_source_off,
        .trg_mask               = POWER_VDDDCTRL_TRG_MASK,
        .bo_irq                 = POWER_CTRL_VDDD_BO_IRQ,
@@ -966,12 +1057,25 @@ static const struct mxs_vddx_cfg mxs_vddd_cfg = {
        .bo_offset_offset       = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
 };
 
+static const struct mxs_vddx_cfg mxs_vdda_cfg = {
+       .reg                    = POWER_REG(hw_power_vddactrl),
+       .step_mV                = 50,
+       .lowest_mV              = 2800,
+       .highest_mV             = 3600,
+       .powered_by_linreg      = mxs_get_vdda_power_source_off,
+       .trg_mask               = POWER_VDDACTRL_TRG_MASK,
+       .bo_irq                 = POWER_CTRL_VDDA_BO_IRQ,
+       .bo_enirq               = POWER_CTRL_ENIRQ_VDDA_BO,
+       .bo_offset_mask         = POWER_VDDACTRL_BO_OFFSET_MASK,
+       .bo_offset_offset       = POWER_VDDACTRL_BO_OFFSET_OFFSET,
+};
+
 #ifdef CONFIG_MX23
 static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vddmemctrl),
+       .reg                    = POWER_REG(hw_power_vddmemctrl),
        .step_mV                = 50,
-       .lowest_mV              = 1700,
+       .lowest_mV              = 1500,
+       .highest_mV             = 1700,
        .powered_by_linreg      = NULL,
        .trg_mask               = POWER_VDDMEMCTRL_TRG_MASK,
        .bo_irq                 = 0,
@@ -996,11 +1100,14 @@ static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
 static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
                                uint32_t new_target, uint32_t new_brownout)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t cur_target, diff, bo_int = 0;
-       uint32_t powered_by_linreg = 0;
-       int adjust_up, tmp;
+       int powered_by_linreg = 0;
+       int adjust_up;
+
+       if (new_target < cfg->lowest_mV)
+               new_target = cfg->lowest_mV;
+       if (new_target > cfg->highest_mV)
+               new_target = cfg->highest_mV;
 
        new_brownout = DIV_ROUND_CLOSEST(new_target - new_brownout,
                                         cfg->step_mV);
@@ -1039,13 +1146,12 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
 
                if (powered_by_linreg ||
                        (readl(&power_regs->hw_power_sts) &
-                               POWER_STS_VDD5V_GT_VDDIO))
+                               POWER_STS_VDD5V_GT_VDDIO)) {
                        early_delay(500);
-               else {
-                       for (;;) {
-                               tmp = readl(&power_regs->hw_power_sts);
-                               if (tmp & POWER_STS_DC_OK)
-                                       break;
+               } else {
+                       while (!(readl(&power_regs->hw_power_sts) &
+                                       POWER_STS_DC_OK)) {
+
                        }
                }
 
@@ -1093,13 +1199,16 @@ static void mxs_setup_batt_detect(void)
 static void mxs_ungate_power(void)
 {
 #ifdef CONFIG_MX23
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
 #endif
 }
 
+#ifdef CONFIG_CONFIG_MACH_MX28EVK
+#define auto_restart 1
+#else
+#define auto_restart 0
+#endif
+
 /**
  * mxs_power_init() - The power block init main function
  *
@@ -1108,34 +1217,44 @@ static void mxs_ungate_power(void)
  */
 void mxs_power_init(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        mxs_ungate_power();
 
        mxs_power_clock2xtal();
-       mxs_power_set_auto_restart();
+       if (mxs_power_set_auto_restart(auto_restart)) {
+               serial_puts("Inconsistent value in RTC_PERSISTENT0 register; power-on-reset required\n");
+       }
        mxs_power_set_linreg();
-       mxs_power_setup_5v_detect();
 
-       mxs_setup_batt_detect();
+       if (!fixed_batt_supply) {
+               mxs_power_setup_5v_detect();
+               mxs_setup_batt_detect();
+       }
 
        mxs_power_configure_power_source();
        mxs_enable_output_rail_protection();
 
-       mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
-       mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
+       mxs_power_set_vddx(&mxs_vddio_cfg, VDDIO_VAL, VDDIO_BO_VAL);
+       mxs_power_set_vddx(&mxs_vddd_cfg, VDDD_VAL, VDDD_BO_VAL);
+       mxs_power_set_vddx(&mxs_vdda_cfg, VDDA_VAL, VDDA_BO_VAL);
 #ifdef CONFIG_MX23
-       mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
+       mxs_power_set_vddx(&mxs_vddmem_cfg, VDDMEM_VAL, VDDMEM_BO_VAL);
+
+       setbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_LINREG);
+       early_delay(500);
+       clrbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_ILIMIT);
+#else
+       clrbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_LINREG);
 #endif
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
                POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
                POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
-
-       writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
-
-       early_delay(1000);
+       if (!fixed_batt_supply)
+               writel(POWER_5VCTRL_PWDN_5VBRNOUT,
+                       &power_regs->hw_power_5vctrl_set);
 }
 
 #ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
@@ -1147,9 +1266,6 @@ void mxs_power_init(void)
  */
 void mxs_power_wait_pswitch(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
                ;
 }
index f2e72257d15b5d77fb7d583152f2b19b1f32a95f..021e21f93928b07fa5b9597fd21fd823f1cfdb59 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define timestamp (gd->arch.tbl)
-#define lastdec (gd->arch.lastinc)
+/* Enable this to verify that the code can correctly
+ * handle the timer rollover
+ */
+/* #define DEBUG_TIMER_WRAP */
+
+#ifdef DEBUG_TIMER_WRAP
+/*
+ * Let the timer wrap 15 seconds after start to catch misbehaving
+ * timer related code early
+ */
+#define TIMER_START            (-time_to_tick(15 * CONFIG_SYS_HZ))
+#else
+#define TIMER_START            0UL
+#endif
 
 /*
  * This driver uses 1kHz clock source.
@@ -42,12 +54,6 @@ static inline unsigned long time_to_tick(unsigned long time)
        return time * (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ);
 }
 
-/* Calculate how many ticks happen in "us" microseconds */
-static inline unsigned long us_to_tick(unsigned long us)
-{
-       return (us * MXS_INCREMENTER_HZ) / 1000000;
-}
-
 int timer_init(void)
 {
        struct mxs_timrot_regs *timrot_regs =
@@ -68,47 +74,73 @@ int timer_init(void)
                TIMROT_TIMCTRLn_SELECT_1KHZ_XTAL,
                &timrot_regs->hw_timrot_timctrl0);
 
-       /* Set fixed_count to maximal value */
+#ifndef DEBUG_TIMER_WRAP
+       /* Set fixed_count to maximum value */
 #if defined(CONFIG_MX23)
        writel(TIMER_LOAD_VAL - 1, &timrot_regs->hw_timrot_timcount0);
 #elif defined(CONFIG_MX28)
        writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
 #endif
-
+#else /* DEBUG_TIMER_WRAP */
+       /* Set fixed_count so that the counter will wrap after 20 seconds */
+#if defined(CONFIG_MX23)
+       writel(20 * MXS_INCREMENTER_HZ - 1, &timrot_regs->hw_timrot_timcount0);
+#elif defined(CONFIG_MX28)
+       writel(20 * MXS_INCREMENTER_HZ,
+               &timrot_regs->hw_timrot_fixed_count0);
+#endif
+       gd->arch.lastinc = TIMER_LOAD_VAL - 20 * MXS_INCREMENTER_HZ;
+
+       /* Make the usec counter roll over 30 seconds after startup */
+       writel(-30000000, MXS_HW_DIGCTL_MICROSECONDS);
+#endif /* DEBUG_TIMER_WRAP */
+       writel(TIMROT_TIMCTRLn_UPDATE,
+               &timrot_regs->hw_timrot_timctrl0_clr);
+#ifdef DEBUG_TIMER_WRAP
+       /* Set fixed_count to maximum value for subsequent loads */
+#if defined(CONFIG_MX23)
+       writel(20 * MXS_INCREMENTER_HZ - 1, &timrot_regs->hw_timrot_timcount0);
+#elif defined(CONFIG_MX28)
+       writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
+#endif
+#endif /* DEBUG_TIMER_WRAP */
+       gd->arch.timer_rate_hz = MXS_INCREMENTER_HZ;
+       gd->arch.tbl = TIMER_START;
+       gd->arch.tbu = 0;
        return 0;
 }
 
+/* Note: This function works correctly for TIMER_LOAD_VAL == 0xffffffff!
+ * The rollover is handled automagically due to the properties of
+ * two's complement arithmetic.
+ * For any other value of TIMER_LOAD_VAL the calculations would have
+ * to be done modulus(TIMER_LOAD_VAL + 1).
+ */
 unsigned long long get_ticks(void)
 {
        struct mxs_timrot_regs *timrot_regs =
                (struct mxs_timrot_regs *)MXS_TIMROT_BASE;
-       uint32_t now;
-
-       /* Current tick value */
+       unsigned long now;
 #if defined(CONFIG_MX23)
        /* Upper bits are the valid ones. */
        now = readl(&timrot_regs->hw_timrot_timcount0) >>
                TIMROT_RUNNING_COUNTn_RUNNING_COUNT_OFFSET;
 #elif defined(CONFIG_MX28)
-       now = readl(&timrot_regs->hw_timrot_running_count0);
+       /* The timer is counting down, so subtract the register value from
+        * the counter period length (implicitly 2^32) to get an incrementing
+        * timestamp
+        */
+       now = -readl(&timrot_regs->hw_timrot_running_count0);
 #else
 #error "Don't know how to read timrot_regs"
 #endif
+       ulong inc = now - gd->arch.lastinc;
 
-       if (lastdec >= now) {
-               /*
-                * normal mode (non roll)
-                * move stamp forward with absolut diff ticks
-                */
-               timestamp += (lastdec - now);
-       } else {
-               /* we have rollover of decrementer */
-               timestamp += (TIMER_LOAD_VAL - now) + lastdec;
-
-       }
-       lastdec = now;
-
-       return timestamp;
+       if (gd->arch.tbl + inc < gd->arch.tbl)
+               gd->arch.tbu++;
+       gd->arch.tbl += inc;
+       gd->arch.lastinc = now;
+       return ((unsigned long long)gd->arch.tbu << 32) | gd->arch.tbl;
 }
 
 ulong get_timer_masked(void)
@@ -118,7 +150,8 @@ ulong get_timer_masked(void)
 
 ulong get_timer(ulong base)
 {
-       return get_timer_masked() - base;
+       /* NOTE: time_to_tick(base) is required to correctly handle rollover! */
+       return tick_to_time(get_ticks() - time_to_tick(base));
 }
 
 /* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
@@ -126,36 +159,19 @@ ulong get_timer(ulong base)
 
 void __udelay(unsigned long usec)
 {
-       uint32_t old, new, incr;
-       uint32_t counter = 0;
-
-       old = readl(MXS_HW_DIGCTL_MICROSECONDS);
-
-       while (counter < usec) {
-               new = readl(MXS_HW_DIGCTL_MICROSECONDS);
-
-               /* Check if the timer wrapped. */
-               if (new < old) {
-                       incr = 0xffffffff - old;
-                       incr += new;
-               } else {
-                       incr = new - old;
-               }
-
-               /*
-                * Check if we are close to the maximum time and the counter
-                * would wrap if incremented. If that's the case, break out
-                * from the loop as the requested delay time passed.
+       uint32_t start = readl(MXS_HW_DIGCTL_MICROSECONDS);
+
+       while (readl(MXS_HW_DIGCTL_MICROSECONDS) - start <= usec)
+               /* use '<=' to guarantee a delay of _at least_
+                * the given number of microseconds.
+                * No need for fancy rollover checks
+                * Two's complement arithmetic applied correctly
+                * does everything that's needed  automagically!
                 */
-               if (counter + incr < counter)
-                       break;
-
-               counter += incr;
-               old = new;
-       }
+               ;
 }
 
 ulong get_tbclk(void)
 {
-       return MXS_INCREMENTER_HZ;
+       return gd->arch.timer_rate_hz;
 }
index c60615a45671a59145aecd43e61a209bd9216b3f..ee9cc75cd1b3c5db9916adb5b7644a293934ce5b 100644 (file)
@@ -1,14 +1,14 @@
 sources {
-       u_boot_spl="spl/u-boot-spl.bin";
-       u_boot="u-boot.bin";
+       u_boot_spl="OBJTREE/spl/u-boot-spl";
+       u_boot="OBJTREE/u-boot";
 }
 
 section (0) {
-       load u_boot_spl > 0x0000;
-       load ivt (entry = 0x0014) > 0x8000;
+       load u_boot_spl;
+       load ivt (entry = u_boot_spl:reset) > 0x8000;
        hab call 0x8000;
 
-       load u_boot > 0x40000100;
-       load ivt (entry = 0x40000100) > 0x8000;
+       load u_boot;
+       load ivt (entry = u_boot:reset) > 0x8000;
        hab call 0x8000;
 }
index 81477aa7b0c3fc9e432a248ca632fc0672a693db..64322b828a0c515187e93eada473481ee612cf1e 100644 (file)
@@ -111,7 +111,7 @@ const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
 #endif
 
 #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
-int cpu_mmc_init(bd_t *bis)
+int __cpu_mmc_init(bd_t *bis)
 {
        int ret;
 
@@ -121,6 +121,8 @@ int cpu_mmc_init(bd_t *bis)
 
        return omap_mmc_init(1, 0, 0, -1, -1);
 }
+/* let platform code be able to override this! */
+int cpu_mmc_init(bd_t *bis) __attribute__((weak, alias("__cpu_mmc_init")));
 #endif
 
 /* AM33XX has two MUSB controllers which can be host or gadget */
index 92142c893444bc63ad7e1b811172c5996d6005a0..23cd9a9fe90dfd14554fa794d4d38db7449c9d04 100644 (file)
 #include <asm/arch/hardware.h>
 #include <asm/io.h>
 
+#define PRCM_MOD_EN            0x2
+#define PRCM_FORCE_WAKEUP      0x2
+#define PRCM_FUNCTL            0x0
+
+#define PRCM_EMIF_CLK_ACTIVITY BIT(2)
+#define PRCM_L3_GCLK_ACTIVITY  BIT(4)
+
+#define PLL_BYPASS_MODE                0x4
+#define ST_MN_BYPASS           0x00000100
+#define ST_DPLL_CLK            0x00000001
+#define CLK_SEL_MASK           0x7ffff
+#define CLK_DIV_MASK           0x1f
+#define CLK_DIV2_MASK          0x7f
+#define CLK_SEL_SHIFT          0x8
+#define CLK_MODE_MASK          0x7
+#define CLK_MODE_SEL           0x7
+#define DPLL_CLKDCOLDO_GATE_CTRL 0x300
+
 #define OSC    (V_OSCK/1000000)
 
+#define MPUPLL_M       CONFIG_SYS_MPUCLK
+#define MPUPLL_N       (OSC - 1)
+#define MPUPLL_M2      1
+
+/* Core PLL Fdll = 1 GHZ, */
+#define COREPLL_M      1000
+#define COREPLL_N      (OSC - 1)
+
+#define COREPLL_M4     10      /* CORE_CLKOUTM4 = 200 MHZ */
+#define COREPLL_M5     8       /* CORE_CLKOUTM5 = 250 MHZ */
+#define COREPLL_M6     4       /* CORE_CLKOUTM6 = 500 MHZ */
+
+/*
+ * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
+ * frequency needs to be set to 960 MHZ. Hence,
+ * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
+ */
+#define PERPLL_M       960
+#define PERPLL_N       (OSC - 1)
+#define PERPLL_M2      5
+
+/* DDR Freq is 266 MHZ for now */
+/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
+#define DDRPLL_M       266
+#define DDRPLL_N       (OSC - 1)
+#define DDRPLL_M2      1
+
 struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER;
 struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP;
 struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL;
@@ -159,3 +204,323 @@ void enable_basic_clocks(void)
        /* Select the Master osc 24 MHZ as Timer2 clock source */
        writel(0x1, &cmdpll->clktimer2clk);
 }
+void mpu_pll_config_val(int mpull_m)
+{
+       u32 clkmode, clksel, div_m2;
+
+       clkmode = readl(&cmwkup->clkmoddpllmpu);
+       clksel = readl(&cmwkup->clkseldpllmpu);
+       div_m2 = readl(&cmwkup->divm2dpllmpu);
+
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllmpu);
+       while (readl(&cmwkup->idlestdpllmpu) != ST_MN_BYPASS)
+               ;
+
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (mpull_m << CLK_SEL_SHIFT) | MPUPLL_N;
+       writel(clksel, &cmwkup->clkseldpllmpu);
+
+       div_m2 &= ~CLK_DIV_MASK;
+       div_m2 |= MPUPLL_M2;
+       writel(div_m2, &cmwkup->divm2dpllmpu);
+
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddpllmpu);
+
+       while (readl(&cmwkup->idlestdpllmpu) != ST_DPLL_CLK)
+               ;
+}
+
+void mpu_pll_config(void)
+{
+       mpu_pll_config_val(CONFIG_SYS_MPUCLK);
+}
+
+static void core_pll_config_val(int m)
+{
+       u32 clkmode, clksel, div_m4, div_m5, div_m6;
+
+       clkmode = readl(&cmwkup->clkmoddpllcore);
+       clksel = readl(&cmwkup->clkseldpllcore);
+       div_m4 = readl(&cmwkup->divm4dpllcore);
+       div_m5 = readl(&cmwkup->divm5dpllcore);
+       div_m6 = readl(&cmwkup->divm6dpllcore);
+
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllcore);
+
+       while (readl(&cmwkup->idlestdpllcore) != ST_MN_BYPASS)
+               ;
+
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= ((m << CLK_SEL_SHIFT) | COREPLL_N);
+       writel(clksel, &cmwkup->clkseldpllcore);
+
+       div_m4 &= ~CLK_DIV_MASK;
+       div_m4 |= COREPLL_M4;
+       writel(div_m4, &cmwkup->divm4dpllcore);
+
+       div_m5 &= ~CLK_DIV_MASK;
+       div_m5 |= COREPLL_M5;
+       writel(div_m5, &cmwkup->divm5dpllcore);
+
+       div_m6 &= ~CLK_DIV_MASK;
+       div_m6 |= COREPLL_M6;
+       writel(div_m6, &cmwkup->divm6dpllcore);
+
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddpllcore);
+
+       while (readl(&cmwkup->idlestdpllcore) != ST_DPLL_CLK)
+               ;
+}
+
+static inline void core_pll_config(void)
+{
+       core_pll_config_val(COREPLL_M);
+}
+
+static void per_pll_config_val(int m)
+{
+       u32 clkmode, clksel, div_m2;
+
+       clkmode = readl(&cmwkup->clkmoddpllper);
+       clksel = readl(&cmwkup->clkseldpllper);
+       div_m2 = readl(&cmwkup->divm2dpllper);
+
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddpllper);
+
+       while (readl(&cmwkup->idlestdpllper) != ST_MN_BYPASS)
+               ;
+
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (m << CLK_SEL_SHIFT) | PERPLL_N;
+       writel(clksel, &cmwkup->clkseldpllper);
+
+       div_m2 &= ~CLK_DIV2_MASK;
+       div_m2 |= PERPLL_M2;
+       writel(div_m2, &cmwkup->divm2dpllper);
+
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddpllper);
+
+       while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
+               ;
+
+       writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
+}
+
+static inline void per_pll_config(void)
+{
+       per_pll_config_val(PERPLL_M);
+}
+
+static void disp_pll_config_val(int m)
+{
+       u32 clkmode, clksel, div_m2;
+
+       clkmode = readl(&cmwkup->clkmoddplldisp);
+       clksel = readl(&cmwkup->clkseldplldisp);
+       div_m2 = readl(&cmwkup->divm2dplldisp);
+
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddplldisp);
+
+       while (!(readl(&cmwkup->idlestdplldisp) & ST_MN_BYPASS))
+               ;
+
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (m << CLK_SEL_SHIFT) | DISPPLL_N;
+       writel(clksel, &cmwkup->clkseldplldisp);
+
+       div_m2 &= ~CLK_DIV2_MASK;
+       div_m2 |= DISPPLL_M2;
+       writel(div_m2, &cmwkup->divm2dplldisp);
+
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddplldisp);
+
+       while (!(readl(&cmwkup->idlestdplldisp) & ST_DPLL_CLK))
+               ;
+}
+
+static inline void disp_pll_config(void)
+{
+       disp_pll_config_val(DISPPLL_M);
+}
+
+void ddr_pll_config(unsigned int ddrpll_m)
+{
+       u32 clkmode, clksel, div_m2;
+
+       clkmode = readl(&cmwkup->clkmoddpllddr);
+       clksel = readl(&cmwkup->clkseldpllddr);
+       div_m2 = readl(&cmwkup->divm2dpllddr);
+
+       /* Set the PLL to bypass Mode */
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= PLL_BYPASS_MODE;
+       writel(clkmode, &cmwkup->clkmoddpllddr);
+
+       /* Wait till bypass mode is enabled */
+       while (!(readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS))
+               ;
+
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N;
+       writel(clksel, &cmwkup->clkseldpllddr);
+
+       div_m2 &= ~CLK_DIV_MASK;
+       div_m2 |= DDRPLL_M2;
+       writel(div_m2, &cmwkup->divm2dpllddr);
+
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddpllddr);
+
+       /* Wait till dpll is locked */
+       while ((readl(&cmwkup->idlestdpllddr) & ST_DPLL_CLK) != ST_DPLL_CLK)
+               ;
+}
+
+#define M(mn) (((mn) & CLK_SEL_MASK) >> CLK_SEL_SHIFT)
+#define N(mn) ((mn) & CLK_DIV2_MASK)
+
+unsigned long __clk_get_rate(u32 m_n, u32 div_m2)
+{
+       unsigned long rate;
+
+       div_m2 &= CLK_DIV_MASK;
+       debug("M=%u N=%u M2=%u\n", M(m_n), N(m_n), div_m2);
+       rate = V_OSCK / 1000 * M(m_n) / (N(m_n) + 1) / div_m2;
+       debug("CLK = %lu.%03luMHz\n", rate / 1000, rate % 1000);
+       return rate * 1000;
+}
+
+unsigned long lcdc_clk_rate(void)
+{
+       return clk_get_rate(cmwkup, disp);
+}
+
+unsigned long mpu_clk_rate(void)
+{
+       return clk_get_rate(cmwkup, mpu);
+}
+
+enum {
+       CLK_MPU_PLL,
+       CLK_CORE_PLL,
+       CLK_PER_PLL,
+       CLK_DISP_PLL,
+       CLK_GPMC,
+};
+
+static struct clk_lookup {
+       const char *name;
+       unsigned int index;
+} am33xx_clk_lookup[] = {
+       { "mpu", CLK_MPU_PLL, },
+       { "core", CLK_CORE_PLL, },
+       { "per", CLK_PER_PLL, },
+       { "lcdc", CLK_DISP_PLL, },
+       { "gpmc", CLK_GPMC, },
+};
+
+#define print_pll(dom, pll) {                          \
+       u32 __pll = clk_get_rate(dom, pll);             \
+       printf("%-12s %4d.%03d MHz\n", #pll,            \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+
+#define print_pll2(dom, n, pll) {                      \
+       u32 __m_n = readl(&(dom)->clkseldpll##pll);     \
+       u32 __div = readl(&(dom)->divm##n##dpll##pll);  \
+       u32 __pll = __clk_get_rate(__m_n, __div);       \
+       printf("%-12s %4d.%03d MHz\n", #pll "_m" #n,    \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+
+static void do_showclocks(void)
+{
+       print_pll(cmwkup, mpu);
+       print_pll2(cmwkup, 4, core);
+       print_pll2(cmwkup, 5, core);
+       print_pll2(cmwkup, 6, core);
+       print_pll(cmwkup, ddr);
+       print_pll(cmwkup, per);
+       print_pll(cmwkup, disp);
+}
+
+int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc,
+       char *const argv[])
+{
+       int i;
+       unsigned long freq;
+       unsigned long __attribute__((unused)) ref = ~0UL;
+
+       if (argc < 2) {
+               do_showclocks();
+               return CMD_RET_SUCCESS;
+       } else if (argc == 2 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+
+       freq = simple_strtoul(argv[2], NULL, 0);
+       if (freq < 1000) {
+               printf("Invalid clock frequency %lu\n", freq);
+               return CMD_RET_FAILURE;
+       }
+       if (argc > 3) {
+               ref = simple_strtoul(argv[3], NULL, 0);
+       }
+       for (i = 0; i < ARRAY_SIZE(am33xx_clk_lookup); i++) {
+               if (strcasecmp(argv[1], am33xx_clk_lookup[i].name) == 0) {
+                       switch (am33xx_clk_lookup[i].index) {
+                       case CLK_MPU_PLL:
+                               mpu_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_CORE_PLL:
+                               core_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_PER_PLL:
+                               per_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_DISP_PLL:
+                               disp_pll_config_val(freq / 1000000);
+                               break;
+                       default:
+                               printf("Cannot change %s clock\n",
+                                       am33xx_clk_lookup[i].name);
+                               return CMD_RET_FAILURE;
+                       }
+
+                       printf("%s clock set to %lu.%03lu MHz\n",
+                               am33xx_clk_lookup[i].name,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return CMD_RET_SUCCESS;
+               }
+       }
+       if (i == ARRAY_SIZE(am33xx_clk_lookup)) {
+               printf("clock %s not found; supported clocks are:\n", argv[1]);
+               for (i = 0; i < ARRAY_SIZE(am33xx_clk_lookup); i++) {
+                       printf("\t%s\n", am33xx_clk_lookup[i].name);
+               }
+       } else {
+               printf("Failed to set clock %s to %s MHz\n",
+                       argv[1], argv[2]);
+       }
+       return CMD_RET_FAILURE;
+}
+
+U_BOOT_CMD(
+       clocks, 4, 0, do_clocks,
+       "display/set clocks",
+       "                    - display clock settings\n"
+       "clocks <clkname> <freq>    - set clock <clkname> to <freq> Hz"
+);
index 85cceae152c2dddf28335cf11846108bef7e7231..07a88c2ed43b987ea1bfdc7878fb36eadce4958a 100644 (file)
  */
 static struct emif_reg_struct *emif_reg[2] = {
                                (struct emif_reg_struct *)EMIF4_0_CFG_BASE,
-                               (struct emif_reg_struct *)EMIF4_1_CFG_BASE};
+                               (struct emif_reg_struct *)EMIF4_1_CFG_BASE,
+};
 
 /**
  * Base addresses for DDR PHY cmd/data regs
  */
 static struct ddr_cmd_regs *ddr_cmd_reg[2] = {
                                (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR,
-                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2};
+                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2,
+};
 
 static struct ddr_data_regs *ddr_data_reg[2] = {
                                (struct ddr_data_regs *)DDR_PHY_DATA_ADDR,
-                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2};
+                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2,
+};
 
 /**
  * Base address for ddr io control instances
  */
-static struct ddr_cmdtctrl *ioctrl_reg = {
-                       (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
+static struct ddr_cmdtctrl *ioctrl_reg =
+                               (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR;
 
 static inline u32 get_mr(int nr, u32 cs, u32 mr_addr)
 {
index 781d83fc72a400f416d7c23b8f3f32b4b924af3a..9d18aaac441810ee746f41b146414e7516390867 100644 (file)
@@ -65,7 +65,7 @@ u32 __weak get_board_rev(void)
 u32 get_device_type(void)
 {
        int mode;
-       mode = readl(&cstat->statusreg) & (DEVICE_MASK);
+       mode = readl(&cstat->statusreg) & DEVICE_MASK;
        return mode >>= 8;
 }
 
@@ -75,22 +75,23 @@ u32 get_device_type(void)
 u32 get_sysboot_value(void)
 {
        int mode;
-       mode = readl(&cstat->statusreg) & (SYSBOOT_MASK);
+       mode = readl(&cstat->statusreg) & SYSBOOT_MASK;
        return mode;
 }
 
 #ifdef CONFIG_DISPLAY_CPUINFO
 static char *cpu_revs[] = {
-               "1.0",
-               "2.0",
-               "2.1"};
-
+       "1.0",
+       "2.0",
+       "2.1",
+};
 
 static char *dev_types[] = {
-               "TST",
-               "EMU",
-               "HS",
-               "GP"};
+       "TST",
+       "EMU",
+       "HS",
+       "GP",
+};
 
 /**
  * Print CPU information
@@ -108,7 +109,6 @@ int print_cpuinfo(void)
                break;
        default:
                cpu_s = "Unknown CPU type";
-               break;
        }
 
        if (get_cpu_rev() < ARRAY_SIZE(cpu_revs))
index 0f9d8377ed5ac568d996257647c9137d6fa60477..8ebe9b0303c9916adbfbc3c08094c38a7b49a196 100644 (file)
@@ -221,16 +221,18 @@ static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op)
 /* Invalidate TLB */
 static void v7_inval_tlb(void)
 {
-       /* Invalidate entire unified TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
-       /* Invalidate entire data TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c6, 0" : : "r" (0));
-       /* Invalidate entire instruction TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0));
-       /* Full system DSB - make sure that the invalidation is complete */
-       CP15DSB;
-       /* Full system ISB - make sure the instruction stream sees it */
-       CP15ISB;
+       asm volatile (
+               /* Invalidate entire unified TLB */
+               "mcr p15, 0, %0, c8, c7, 0\n"
+               /* Invalidate entire data TLB */
+               "mcr p15, 0, %0, c8, c6, 0\n"
+               /* Invalidate entire instruction TLB */
+               "mcr p15, 0, %0, c8, c5, 0\n"
+               /* Full system DSB - make sure that the invalidation is complete */
+               "mcr     p15, 0, %0, c7, c10, 4\n"
+               /* Full system ISB - make sure the instruction stream sees it */
+               "mcr     p15, 0, %0, c7, c5, 4\n"
+               : : "r" (0));
 }
 
 void invalidate_dcache_all(void)
@@ -337,16 +339,15 @@ void invalidate_icache_all(void)
         * Invalidate all instruction caches to PoU.
         * Also flushes branch target cache.
         */
-       asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
-
-       /* Invalidate entire branch predictor array */
-       asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
-
-       /* Full system DSB - make sure that the invalidation is complete */
-       CP15DSB;
-
-       /* ISB - make sure the instruction stream sees it */
-       CP15ISB;
+       asm volatile (
+               "mcr p15, 0, %0, c7, c5, 0\n"
+               /* Invalidate entire branch predictor array */
+               "mcr p15, 0, %0, c7, c5, 6\n"
+               /* Full system DSB - make sure that the invalidation is complete */
+               "mcr     p15, 0, %0, c7, c10, 4\n"
+               /* ISB - make sure the instruction stream sees it */
+               "mcr     p15, 0, %0, c7, c5, 4\n"
+               : : "r" (0));
 }
 #else
 void invalidate_icache_all(void)
index c56417dd2f1ec81d8fa1088d8c12fc0aaf6c3848..f381d2ff9872f13464f16e5e3eb414150ab2cc61 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <lcd.h>
 #include <asm/system.h>
 #include <asm/cache.h>
 #include <asm/armv7.h>
@@ -34,7 +35,15 @@ int cleanup_before_linux(void)
         */
 #ifndef CONFIG_SPL_BUILD
        disable_interrupts();
-#endif
+#ifdef CONFIG_LCD
+       {
+               /* switch off LCD panel */
+               lcd_panel_disable();
+               /* disable LCD controller */
+               lcd_disable();
+       }
+#endif /* CONFIG_LCD */
+#endif /* CONFIG_SPL_BUILD */
 
        /*
         * Turn off I-cache and invalidate it
index f1aea05c9094677c8e7c6bf8126d8d4ab970ba30..d71c84fae5b85adcd7d170542728973a1e87e734 100644 (file)
@@ -19,7 +19,11 @@ ENTRY(lowlevel_init)
        /*
         * Setup a temporary stack
         */
+#ifndef CONFIG_SPL_BUILD
        ldr     sp, =CONFIG_SYS_INIT_SP_ADDR
+#else
+       ldr     sp, =CONFIG_SPL_STACK
+#endif
        bic     sp, sp, #7 /* 8-byte alignment for ABI compliance */
 #ifdef CONFIG_SPL_BUILD
        ldr     r9, =gdata
index bf52f0d19e546e0b98b2717b25618c4c6711e92b..443fb997826244080a4dd3d4ce7a1a979ee1e802 100644 (file)
@@ -46,15 +46,14 @@ struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = {
 #define EMI_DIV_MAX     8
 #define NFC_DIV_MAX     8
 
-#define MX5_CBCMR      0x00015154
-#define MX5_CBCDR      0x02888945
+#define MXC_IPG_PER_CLK        MXC_IPG_PERCLK
 
 struct fixed_pll_mfd {
        u32 ref_clk_hz;
        u32 mfd;
 };
 
-const struct fixed_pll_mfd fixed_mfd[] = {
+static const struct fixed_pll_mfd fixed_mfd[] = {
        {MXC_HCLK, 24 * 16},
 };
 
@@ -67,12 +66,102 @@ struct pll_param {
 
 #define PLL_FREQ_MAX(ref_clk)  (4 * (ref_clk) * PLL_MFI_MAX)
 #define PLL_FREQ_MIN(ref_clk) \
-               ((2 * (ref_clk) * (PLL_MFI_MIN - 1)) / PLL_PD_MAX)
+       ((4 * (ref_clk) * PLL_MFI_MIN) / PLL_PD_MAX)
 #define MAX_DDR_CLK     420000000
 #define NFC_CLK_MAX     34000000
 
 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
 
+int clk_enable(struct clk *clk)
+{
+       int ret = 0;
+
+       if (!clk)
+               return 0;
+
+       if (clk->usecount++ == 0) {
+               if (!clk->enable)
+                       return 0;
+               ret = clk->enable(clk);
+               if (ret)
+                       clk->usecount--;
+       }
+       return ret;
+}
+
+void clk_disable(struct clk *clk)
+{
+       if (!clk)
+               return;
+
+       if (!(--clk->usecount)) {
+               if (clk->disable)
+                       clk->disable(clk);
+       }
+       if (clk->usecount < 0) {
+               printf("%s: clk %p (%s) underflow\n", __func__, clk, clk->name);
+               hang();
+       }
+}
+
+int clk_get_usecount(struct clk *clk)
+{
+       if (clk == NULL)
+               return 0;
+
+       return clk->usecount;
+}
+
+u32 clk_get_rate(struct clk *clk)
+{
+       if (!clk)
+               return 0;
+
+       return clk->rate;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+       if (!clk)
+               return 0;
+
+       return clk->parent;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk && clk->set_rate)
+               clk->set_rate(clk, rate);
+       return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk == NULL || !clk->round_rate)
+               return 0;
+
+       return clk->round_rate(clk, rate);
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       debug("Setting parent of clk %p to %p (%p)\n", clk, parent,
+               clk ? clk->parent : NULL);
+
+       if (!clk || clk == parent)
+               return 0;
+
+       if (clk->set_parent) {
+               int ret;
+
+               ret = clk->set_parent(clk, parent);
+               if (ret)
+                       return ret;
+       }
+       clk->parent = parent;
+       return 0;
+}
+
 void set_usboh3_clk(void)
 {
        clrsetbits_le32(&mxc_ccm->cscmr1,
@@ -94,6 +183,100 @@ void enable_usboh3_clk(bool enable)
                        MXC_CCM_CCGR2_USBOH3_60M(cg));
 }
 
+void ipu_clk_enable(void)
+{
+       /* IPU root clock derived from AXI B */
+       clrsetbits_le32(&mxc_ccm->cbcmr, MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK,
+                       MXC_CCM_CBCMR_IPU_HSP_CLK_SEL(1));
+
+       setbits_le32(&mxc_ccm->CCGR5,
+               MXC_CCM_CCGR5_IPU(MXC_CCM_CCGR_CG_MASK));
+
+       /* Handshake with IPU when certain clock rates are changed. */
+       clrbits_le32(&mxc_ccm->ccdr, MXC_CCM_CCDR_IPU_HS_MASK);
+
+       /* Handshake with IPU when LPM is entered as its enabled. */
+       clrbits_le32(&mxc_ccm->clpcr, MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS);
+}
+
+void ipu_clk_disable(void)
+{
+       clrbits_le32(&mxc_ccm->CCGR5,
+               MXC_CCM_CCGR5_IPU(MXC_CCM_CCGR_CG_MASK));
+
+       /* Handshake with IPU when certain clock rates are changed. */
+       setbits_le32(&mxc_ccm->ccdr, MXC_CCM_CCDR_IPU_HS_MASK);
+
+       /* Handshake with IPU when LPM is entered as its enabled. */
+       setbits_le32(&mxc_ccm->clpcr, MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS);
+}
+
+void ipu_di_clk_enable(int di)
+{
+       switch (di) {
+       case 0:
+               setbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_IPU_DI0(MXC_CCM_CCGR_CG_MASK));
+               break;
+       case 1:
+               setbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_IPU_DI1(MXC_CCM_CCGR_CG_MASK));
+               break;
+       default:
+               printf("%s: Invalid DI index %d\n", __func__, di);
+       }
+}
+
+void ipu_di_clk_disable(int di)
+{
+       switch (di) {
+       case 0:
+               clrbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_IPU_DI0(MXC_CCM_CCGR_CG_MASK));
+               break;
+       case 1:
+               clrbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_IPU_DI1(MXC_CCM_CCGR_CG_MASK));
+               break;
+       default:
+               printf("%s: Invalid DI index %d\n", __func__, di);
+       }
+}
+
+#ifdef CONFIG_MX53
+void ldb_clk_enable(int ldb)
+{
+       switch (ldb) {
+       case 0:
+               setbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_LDB_DI0(MXC_CCM_CCGR_CG_MASK));
+               break;
+       case 1:
+               setbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_LDB_DI1(MXC_CCM_CCGR_CG_MASK));
+               break;
+       default:
+               printf("%s: Invalid LDB index %d\n", __func__, ldb);
+       }
+}
+
+void ldb_clk_disable(int ldb)
+{
+       switch (ldb) {
+       case 0:
+               clrbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_LDB_DI0(MXC_CCM_CCGR_CG_MASK));
+               break;
+       case 1:
+               clrbits_le32(&mxc_ccm->CCGR6,
+                       MXC_CCM_CCGR6_LDB_DI1(MXC_CCM_CCGR_CG_MASK));
+               break;
+       default:
+               printf("%s: Invalid LDB index %d\n", __func__, ldb);
+       }
+}
+#endif
+
 #ifdef CONFIG_SYS_I2C_MXC
 /* i2c_num can be from 0, to 1 for i.MX51 and 2 for i.MX53 */
 int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
@@ -160,9 +343,10 @@ void enable_usb_phy2_clk(bool enable)
  */
 static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq)
 {
-       uint32_t ctrl, op, mfd, mfn, mfi, pdf, ret;
+       uint32_t ctrl, op;
+       int mfd, mfn, mfi, pdf, ret;
        uint64_t refclk, temp;
-       int32_t mfn_abs;
+       uint32_t mfn_abs;
 
        ctrl = readl(&pll->ctrl);
 
@@ -189,23 +373,23 @@ static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq)
        if (mfn >= 0x04000000) {
                mfn |= 0xfc000000;
                mfn_abs = -mfn;
-       } else
+       } else {
                mfn_abs = mfn;
-
+       }
        refclk = infreq * 2;
        if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN)
                refclk *= 2;
 
-       do_div(refclk, pdf + 1);
        temp = refclk * mfn_abs;
        do_div(temp, mfd + 1);
        ret = refclk * mfi;
 
-       if ((int)mfn < 0)
+       if (mfn < 0)
                ret -= temp;
        else
                ret += temp;
 
+       ret /= pdf + 1;
        return ret;
 }
 
@@ -444,6 +628,17 @@ static u32 get_emi_slow_clk(void)
        return  get_periph_clk() / (pdf + 1);
 }
 
+static u32 get_nfc_clk(void)
+{
+       u32 parent_rate = get_emi_slow_clk();
+       u32 div = readl(&mxc_ccm->cbcdr);
+
+       div &= MXC_CCM_CBCDR_NFC_PODF_MASK;
+       div >>= MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+       div++;
+       return parent_rate / div;
+}
+
 static u32 get_ddr_clk(void)
 {
        u32 ret_val = 0;
@@ -513,6 +708,14 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
                return get_ahb_clk();
        case MXC_DDR_CLK:
                return get_ddr_clk();
+       case MXC_AXI_A_CLK:
+               return get_axi_a_clk();
+       case MXC_AXI_B_CLK:
+               return get_axi_b_clk();
+       case MXC_EMI_SLOW_CLK:
+               return get_emi_slow_clk();
+       case MXC_NFC_CLK:
+               return get_nfc_clk();
        default:
                break;
        }
@@ -551,18 +754,17 @@ static int gcd(int m, int n)
  */
 static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
 {
-       u64 pd, mfi = 1, mfn, mfd, t1;
-       u32 n_target = target;
-       u32 n_ref = ref, i;
+       int pd, mfi = 1, mfn, mfd;
+       u64 t1;
+       size_t i;
 
        /*
         * Make sure targeted freq is in the valid range.
         * Otherwise the following calculation might be wrong!!!
         */
-       if (n_target < PLL_FREQ_MIN(ref) ||
-               n_target > PLL_FREQ_MAX(ref)) {
-               printf("Targeted peripheral clock should be"
-                       "within [%d - %d]\n",
+       if (target < PLL_FREQ_MIN(ref) ||
+               target > PLL_FREQ_MAX(ref)) {
+               printf("Targeted pll clock should be within [%d - %d]\n",
                        PLL_FREQ_MIN(ref) / SZ_DEC_1M,
                        PLL_FREQ_MAX(ref) / SZ_DEC_1M);
                return -EINVAL;
@@ -578,10 +780,9 @@ static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
        if (i == ARRAY_SIZE(fixed_mfd))
                return -EINVAL;
 
-       /* Use n_target and n_ref to avoid overflow */
        for (pd = 1; pd <= PLL_PD_MAX; pd++) {
-               t1 = n_target * pd;
-               do_div(t1, (4 * n_ref));
+               t1 = (u64)target * pd;
+               do_div(t1, (4 * ref));
                mfi = t1;
                if (mfi > PLL_MFI_MAX)
                        return -EINVAL;
@@ -592,25 +793,26 @@ static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
        /*
         * Now got pd and mfi already
         *
-        * mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref;
+        * mfn = (((target * pd) / 4 - ref * mfi) * mfd) / ref;
         */
-       t1 = n_target * pd;
+       t1 = (u64)target * pd;
        do_div(t1, 4);
-       t1 -= n_ref * mfi;
-       t1 *= mfd;
-       do_div(t1, n_ref);
+       t1 = (t1 - ref * mfi) * mfd;
+       do_div(t1, ref);
        mfn = t1;
-       debug("ref=%d, target=%d, pd=%d," "mfi=%d,mfn=%d, mfd=%d\n",
-               ref, n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd);
-       i = 1;
-       if (mfn != 0)
+       if (mfn != 0) {
                i = gcd(mfd, mfn);
-       pll->pd = (u32)pd;
-       pll->mfi = (u32)mfi;
-       do_div(mfn, i);
-       pll->mfn = (u32)mfn;
-       do_div(mfd, i);
-       pll->mfd = (u32)mfd;
+               mfn /= i;
+               mfd /= i;
+       } else {
+               mfd = 1;
+       }
+       debug("ref=%d, target=%d, pd=%d, mfi=%d, mfn=%d, mfd=%d\n",
+               ref, target, pd, mfi, mfn, mfd);
+       pll->pd = pd;
+       pll->mfi = mfi;
+       pll->mfn = mfn;
+       pll->mfd = mfd;
 
        return 0;
 }
@@ -628,71 +830,63 @@ static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
 
 #define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \
        {       \
-               writel(0x1232, &pll->ctrl);             \
-               writel(0x2, &pll->config);              \
-               writel((((pd) - 1) << 0) | ((fi) << 4), \
-                       &pll->op);                      \
-               writel(fn, &(pll->mfn));                \
-               writel((fd) - 1, &pll->mfd);            \
-               writel((((pd) - 1) << 0) | ((fi) << 4), \
-                       &pll->hfs_op);                  \
-               writel(fn, &pll->hfs_mfn);              \
-               writel((fd) - 1, &pll->hfs_mfd);        \
-               writel(0x1232, &pll->ctrl);             \
-               while (!readl(&pll->ctrl) & 0x1)        \
+               __raw_writel(0x1232, &pll->ctrl);               \
+               __raw_writel(0x2, &pll->config);                \
+               __raw_writel((((pd) - 1) << 0) | ((fi) << 4),   \
+                       &pll->op);                              \
+               __raw_writel(fn, &(pll->mfn));                  \
+               __raw_writel((fd) - 1, &pll->mfd);              \
+               __raw_writel((((pd) - 1) << 0) | ((fi) << 4),   \
+                       &pll->hfs_op);                          \
+               __raw_writel(fn, &pll->hfs_mfn);                \
+               __raw_writel((fd) - 1, &pll->hfs_mfd);          \
+               __raw_writel(0x1232, &pll->ctrl);               \
+               while (!__raw_readl(&pll->ctrl) & 0x1)          \
                        ;\
        }
 
 static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param)
 {
-       u32 ccsr = readl(&mxc_ccm->ccsr);
+       u32 ccsr = __raw_readl(&mxc_ccm->ccsr);
        struct mxc_pll_reg *pll = mxc_plls[index];
 
        switch (index) {
        case PLL1_CLOCK:
                /* Switch ARM to PLL2 clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL1_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x4, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x4, &mxc_ccm->ccsr);
                break;
        case PLL2_CLOCK:
                /* Switch to pll2 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL2_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x2, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x2, &mxc_ccm->ccsr);
                break;
        case PLL3_CLOCK:
                /* Switch to pll3 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL3_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x1, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x1, &mxc_ccm->ccsr);
                break;
 #ifdef CONFIG_MX53
        case PLL4_CLOCK:
                /* Switch to pll4 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL4_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x20, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL4_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x20, &mxc_ccm->ccsr);
                break;
 #endif
        default:
@@ -702,22 +896,60 @@ static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param)
        return 0;
 }
 
+static int __adjust_core_voltage_stub(u32 freq)
+{
+       return 0;
+}
+int adjust_core_voltage(u32 freq)
+       __attribute__((weak, alias("__adjust_core_voltage_stub")));
+
 /* Config CPU clock */
 static int config_core_clk(u32 ref, u32 freq)
 {
        int ret = 0;
        struct pll_param pll_param;
+       u32 cur_freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
+
+       if (freq == cur_freq)
+               return 0;
 
        memset(&pll_param, 0, sizeof(struct pll_param));
 
        /* The case that periph uses PLL1 is not considered here */
        ret = calc_pll_params(ref, freq, &pll_param);
        if (ret != 0) {
-               printf("Error:Can't find pll parameters: %d\n", ret);
+               printf("Error: Can't find pll parameters for %u.%03uMHz ref %u.%03uMHz\n",
+                       freq / 1000000, freq / 1000 % 1000,
+                       ref / 1000000, ref / 1000 % 1000);
                return ret;
        }
-
-       return config_pll_clk(PLL1_CLOCK, &pll_param);
+       if (freq > cur_freq) {
+               ret = adjust_core_voltage(freq);
+               if (ret < 0) {
+                       printf("Failed to adjust core voltage for changing ARM clk from %u.%03uMHz to  %u.%03uMHz\n",
+                               cur_freq / 1000000, cur_freq / 1000 % 1000,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return ret;
+               }
+               ret = config_pll_clk(PLL1_CLOCK, &pll_param);
+               if (ret) {
+                       adjust_core_voltage(cur_freq);
+               }
+       } else {
+               ret = config_pll_clk(PLL1_CLOCK, &pll_param);
+               if (ret) {
+                       return ret;
+               }
+               ret = adjust_core_voltage(freq);
+               if (ret < 0) {
+                       printf("Failed to adjust core voltage for changing ARM clk from %u.%03uMHz to  %u.%03uMHz\n",
+                               cur_freq / 1000000, cur_freq / 1000 % 1000,
+                               freq / 1000000, freq / 1000 % 1000);
+                       calc_pll_params(ref, cur_freq, &pll_param);
+                       config_pll_clk(PLL1_CLOCK, &pll_param);
+               }
+       }
+       return ret;
 }
 
 static int config_nfc_clk(u32 nfc_clk)
@@ -914,36 +1146,118 @@ void mxc_set_sata_internal_clock(void)
 /*
  * Dump some core clockes.
  */
-int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+#define pr_clk_val(c, v) {                                     \
+       printf("%-11s %3lu.%03lu MHz\n", #c,                    \
+               (v) / 1000000, (v) / 1000 % 1000);              \
+}
+
+#define pr_clk(c) {                                            \
+       unsigned long __clk = mxc_get_clock(MXC_##c##_CLK);     \
+       pr_clk_val(c, __clk);                                   \
+}
+
+static int do_mx5_showclocks(void)
 {
-       u32 freq;
+       unsigned long freq;
 
        freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
-       printf("PLL1       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL1, freq);
        freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK);
-       printf("PLL2       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL2, freq);
        freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK);
-       printf("PLL3       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL3, freq);
 #ifdef CONFIG_MX53
        freq = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK);
-       printf("PLL4       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL4, freq);
 #endif
 
        printf("\n");
-       printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
-       printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
-       printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
-       printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
+       pr_clk(AHB);
+       pr_clk(AXI_A);
+       pr_clk(AXI_B);
+       pr_clk(IPG);
+       pr_clk(IPG_PER);
+       pr_clk(DDR);
+       pr_clk(EMI_SLOW);
+       pr_clk(NFC);
 #ifdef CONFIG_MXC_SPI
-       printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
+       pr_clk(CSPI);
 #endif
        return 0;
 }
 
+static struct clk_lookup {
+       const char *name;
+       unsigned int index;
+} mx5_clk_lookup[] = {
+       { "arm", MXC_ARM_CLK, },
+};
+
+int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int i;
+       unsigned long freq;
+       unsigned long ref = ~0UL;
+
+       if (argc < 2) {
+               do_mx5_showclocks();
+               return CMD_RET_SUCCESS;
+       } else if (argc == 2 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+
+       freq = simple_strtoul(argv[2], NULL, 0);
+       if (freq == 0) {
+               printf("Invalid clock frequency %lu\n", freq);
+               return CMD_RET_FAILURE;
+       }
+       if (argc > 3) {
+               ref = simple_strtoul(argv[3], NULL, 0);
+       }
+       for (i = 0; i < ARRAY_SIZE(mx5_clk_lookup); i++) {
+               if (strcasecmp(argv[1], mx5_clk_lookup[i].name) == 0) {
+                       switch (mx5_clk_lookup[i].index) {
+                       case MXC_ARM_CLK:
+                               if (argc > 3)
+                                       return CMD_RET_USAGE;
+                               ref = CONFIG_SYS_MX5_HCLK;
+                               break;
+
+                       case MXC_NFC_CLK:
+                               if (argc > 3 && ref > 3) {
+                                       printf("Invalid clock selector value: %lu\n", ref);
+                                       return CMD_RET_FAILURE;
+                               }
+                               break;
+                       }
+                       printf("Setting %s clock to %lu MHz\n",
+                               mx5_clk_lookup[i].name, freq);
+                       if (mxc_set_clock(ref, freq, mx5_clk_lookup[i].index))
+                               break;
+                       freq = mxc_get_clock(mx5_clk_lookup[i].index);
+                       printf("%s clock set to %lu.%03lu MHz\n",
+                               mx5_clk_lookup[i].name,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return CMD_RET_SUCCESS;
+               }
+       }
+       if (i == ARRAY_SIZE(mx5_clk_lookup)) {
+               printf("clock %s not found; supported clocks are:\n", argv[1]);
+               for (i = 0; i < ARRAY_SIZE(mx5_clk_lookup); i++) {
+                       printf("\t%s\n", mx5_clk_lookup[i].name);
+               }
+       } else {
+               printf("Failed to set clock %s to %s MHz\n",
+                       argv[1], argv[2]);
+       }
+       return CMD_RET_FAILURE;
+}
+
 /***************************************************/
 
 U_BOOT_CMD(
-       clocks, CONFIG_SYS_MAXARGS, 1, do_mx5_showclocks,
-       "display clocks",
-       ""
+       clocks, 4, 0, do_clocks,
+       "display/set clocks",
+       "                    - display clock settings\n"
+       "clocks <clkname> <freq>    - set clock <clkname> to <freq> MHz"
 );
index f5bc6728b7c2ce4cbe4bcbdef260b39d1cfc1e32..3e7746b9bfde65b1f81ad995c446007e66c47e89 100644 (file)
@@ -97,7 +97,7 @@
 .endm /* init_m4if */
 
 .macro setup_pll pll, freq
-       ldr r0, =\pll
+       ldr r3, =\pll
        adr r2, W_DP_\freq
        bl setup_pll_func
 .endm
 
 setup_pll_func:
        ldr r1, =0x00001232
-       str r1, [r0, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
+       str r1, [r3, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
        mov r1, #0x2
-       str r1, [r0, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
+       str r1, [r3, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
 
        ldr r1, [r2, #W_DP_OP]
-       str r1, [r0, #PLL_DP_OP]
-       str r1, [r0, #PLL_DP_HFS_OP]
+       str r1, [r3, #PLL_DP_OP]
+       str r1, [r3, #PLL_DP_HFS_OP]
 
        ldr r1, [r2, #W_DP_MFD]
-       str r1, [r0, #PLL_DP_MFD]
-       str r1, [r0, #PLL_DP_HFS_MFD]
+       str r1, [r3, #PLL_DP_MFD]
+       str r1, [r3, #PLL_DP_HFS_MFD]
 
        ldr r1, [r2, #W_DP_MFN]
-       str r1, [r0, #PLL_DP_MFN]
-       str r1, [r0, #PLL_DP_HFS_MFN]
+       str r1, [r3, #PLL_DP_MFN]
+       str r1, [r3, #PLL_DP_HFS_MFN]
 
        ldr r1, =0x00001232
-       str r1, [r0, #PLL_DP_CTL]
-1:     ldr r1, [r0, #PLL_DP_CTL]
+       str r1, [r3, #PLL_DP_CTL]
+1:     ldr r1, [r3, #PLL_DP_CTL]
        ands r1, r1, #0x1
        beq 1b
 
@@ -162,10 +162,9 @@ setup_pll_func:
 .endm
 
 .macro init_clock
-#if defined (CONFIG_MX51)
        ldr r0, =CCM_BASE_ADDR
-
-       /* Gate of clocks to the peripherals first */
+#if defined (CONFIG_MX51)
+       /* Gate off clocks to the peripherals first */
        ldr r1, =0x3FFFFFFF
        str r1, [r0, #CLKCTL_CCGR0]
        str r4, [r0, #CLKCTL_CCGR1]
@@ -188,7 +187,7 @@ setup_pll_func:
        str r1, [r0, #CLKCTL_CBCDR]
        /* make sure divider effective */
 1:     ldr r1, [r0, #CLKCTL_CDHIPR]
-       cmp r1, #0x0
+       tst r1, #0x7f
        bne 1b
 
        /* Switch ARM to step clock */
@@ -199,13 +198,18 @@ setup_pll_func:
        setup_pll PLL1_BASE_ADDR, 864
        setup_pll_errata PLL1_BASE_ADDR, W_DP_MFN_800_DIT
 #else
+#if !defined(CONFIG_SYS_CPU_CLK) || CONFIG_SYS_CPU_CLK == 800
        setup_pll PLL1_BASE_ADDR, 800
+#elif CONFIG_SYS_CPU_CLK == 600
+       setup_pll PLL1_BASE_ADDR, 600
+#else
+#error Unsupported CONFIG_SYS_CPU_CLK value
+#endif
 #endif
 
        setup_pll PLL3_BASE_ADDR, 665
 
        /* Switch peripheral to PLL 3 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x000010C0 | CONFIG_SYS_DDR_CLKSEL
        str r1, [r0, #CLKCTL_CBCMR]
        ldr r1, =0x13239145
@@ -213,7 +217,6 @@ setup_pll_func:
        setup_pll PLL2_BASE_ADDR, 665
 
        /* Switch peripheral to PLL2 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x19239145
        str r1, [r0, #CLKCTL_CBCDR]
        ldr r1, =0x000020C0 | CONFIG_SYS_DDR_CLKSEL
@@ -264,7 +267,7 @@ setup_pll_func:
        str r1, [r0, #CLKCTL_CSCDR1]
        /* make sure divider effective */
 1:     ldr r1, [r0, #CLKCTL_CDHIPR]
-       cmp r1, #0x0
+       tst r1, #0x7f
        bne 1b
 
        str r4, [r0, #CLKCTL_CCDR]
@@ -274,9 +277,7 @@ setup_pll_func:
        add r1, r1, #0x00000F0
        str r1, [r0, #CLKCTL_CCOSR]
 #else  /* CONFIG_MX53 */
-       ldr r0, =CCM_BASE_ADDR
-
-       /* Gate of clocks to the peripherals first */
+       /* Gate off clocks to the peripherals first */
        ldr r1, =0x3FFFFFFF
        str r1, [r0, #CLKCTL_CCGR0]
        str r4, [r0, #CLKCTL_CCGR1]
@@ -294,10 +295,16 @@ setup_pll_func:
        mov r1, #0x4
        str r1, [r0, #CLKCTL_CCSR]
 
+#if !defined(CONFIG_SYS_CPU_CLK) || CONFIG_SYS_CPU_CLK == 800
        setup_pll PLL1_BASE_ADDR, 800
+#elif CONFIG_SYS_CPU_CLK == 600
+       setup_pll PLL1_BASE_ADDR, 600
+#else
+#error Unsupported CONFIG_SYS_CPU_CLK value
+#endif
 
        setup_pll PLL3_BASE_ADDR, 400
-
+#ifndef CONFIG_TX53
        /* Switch peripheral to PLL3 */
        ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x00015154
@@ -306,34 +313,71 @@ setup_pll_func:
        str r1, [r0, #CLKCTL_CBCDR]
        /* make sure change is effective */
 1:      ldr r1, [r0, #CLKCTL_CDHIPR]
-       cmp r1, #0x0
+       tst r1, #0x7f
        bne 1b
 
        setup_pll PLL2_BASE_ADDR, 400
 
        /* Switch peripheral to PLL2 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x00888945
        str r1, [r0, #CLKCTL_CBCDR]
 
        ldr r1, =0x00016154
        str r1, [r0, #CLKCTL_CBCMR]
 
-       /*change uart clk parent to pll2*/
+       /* change uart clk parent to pll2 */
        ldr r1, [r0, #CLKCTL_CSCMR1]
-       and r1, r1, #0xfcffffff
-       orr r1, r1, #0x01000000
+       bic r1, #(0x3 << 24)
+       orr r1, r1, #(0x1 << 24)
        str r1, [r0, #CLKCTL_CSCMR1]
 
        /* make sure change is effective */
 1:      ldr r1, [r0, #CLKCTL_CDHIPR]
-       cmp r1, #0x0
+       tst r1, #0x7f
        bne 1b
 
        setup_pll PLL3_BASE_ADDR, 216
 
        setup_pll PLL4_BASE_ADDR, 455
 
+#else /* CONFIG_TX53 */
+       /* Switch peripheral to PLL 3 */
+       ldr r1, [r0, #CLKCTL_CBCMR]
+       bic r1, #(0x3 << 12)
+       orr r1, r1, #(1 << 12)
+       str r1, [r0, #CLKCTL_CBCMR]
+
+       ldr r1, [r0, #CLKCTL_CBCDR]
+       orr r1, r1, #(1 << 25)
+       str r1, [r0, #CLKCTL_CBCDR]
+1:
+       /* make sure change is effective */
+       ldr r1, [r0, #CLKCTL_CDHIPR]
+       tst r1, #0x7f
+       bne 1b
+
+#if CONFIG_SYS_SDRAM_CLK == 533
+       setup_pll PLL2_BASE_ADDR, 533
+#elif CONFIG_SYS_SDRAM_CLK == 400
+       setup_pll PLL2_BASE_ADDR, 400
+#elif CONFIG_SYS_SDRAM_CLK == 333
+       setup_pll PLL2_BASE_ADDR, 333
+#else
+#error Unsupported CONFIG_SYS_SDRAM_CLK
+#endif
+
+       /* Switch peripheral to PLL2 */
+       ldr r1, [r0, #CLKCTL_CBCDR]
+       bic r1, #(1 << 25)
+       str r1, [r0, #CLKCTL_CBCDR]
+
+       ldr r1, [r0, #CLKCTL_CBCMR]
+       bic r1, #(3 << 12)
+       orr r1, #(2 << 12)
+       str r1, [r0, #CLKCTL_CBCMR]
+#endif
+        setup_pll PLL3_BASE_ADDR, 216
+
        /* Set the platform clock dividers */
        ldr r0, =ARM_BASE_ADDR
        ldr r1, =0x00000124
@@ -349,9 +393,13 @@ setup_pll_func:
 
        /* make uart div=6 */
        ldr r1, [r0, #CLKCTL_CSCDR1]
-       and r1, r1, #0xffffffc0
+       bic r1, #(0x3f << 0)
        orr r1, r1, #0x0a
        str r1, [r0, #CLKCTL_CSCDR1]
+       /* make sure divider effective */
+1:     ldr r1, [r0, #CLKCTL_CDHIPR]
+       tst r1, #0x7f
+       bne 1b
 
        /* Restore the default values in the Gate registers */
        ldr r1, =0xFFFFFFFF
@@ -417,6 +465,9 @@ W_DP_800:           .word DP_OP_800
 W_DP_665:              .word DP_OP_665
                        .word DP_MFD_665
                        .word DP_MFN_665
+W_DP_600:              .word DP_OP_600
+                       .word DP_MFD_600
+                       .word DP_MFN_600
 #endif
 W_DP_216:              .word DP_OP_216
                        .word DP_MFD_216
@@ -427,3 +478,6 @@ W_DP_400:               .word DP_OP_400
 W_DP_455:               .word DP_OP_455
                        .word DP_MFD_455
                        .word DP_MFN_455
+W_DP_533:              .word DP_OP_533
+                       .word DP_MFD_533
+                       .word DP_MFN_533
index 3753c14df3977c7b70459d5db2e3df0a05791f95..95564a8257d33fb1e3b8b6a0fa13a3cb87d33b99 100644 (file)
 #error "CPU_TYPE not defined"
 #endif
 
+#ifdef CONFIG_HW_WATCHDOG
+#define wdog_base      ((void *)WDOG1_BASE_ADDR)
+#define WDOG_WCR       0x00
+#define WCR_WDE                (1 << 2)
+#define WDOG_WSR       0x02
+
+void hw_watchdog_reset(void)
+{
+       if (readw(wdog_base + WDOG_WCR) & WCR_WDE) {
+               static u16 toggle = 0xaaaa;
+
+               writew(toggle, wdog_base + WDOG_WSR);
+               toggle ^= 0xffff;
+       }
+}
+#endif
+
 u32 get_cpu_rev(void)
 {
 #ifdef CONFIG_MX51
@@ -72,7 +89,7 @@ void enable_caches(void)
 #endif
 
 #if defined(CONFIG_FEC_MXC)
-void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+static void __imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 {
        int i;
        struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
@@ -83,6 +100,10 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
        for (i = 0; i < 6; i++)
                mac[i] = readl(&fuse->mac_addr[i]) & 0xff;
 }
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+       __attribute__((weak, alias("__imx_get_mac_from_fuse")));
+
 #endif
 
 #ifdef CONFIG_MX53
diff --git a/arch/arm/cpu/armv7/mx6/asm-offsets.c b/arch/arm/cpu/armv7/mx6/asm-offsets.c
new file mode 100644 (file)
index 0000000..77699c2
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Adapted from Linux v2.6.36 kernel: arch/powerpc/kernel/asm-offsets.c
+ *
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+
+#include <linux/kbuild.h>
+
+int main(void)
+{
+       DEFINE(CCM_CCR, offsetof(struct mxc_ccm_reg, ccr));
+       DEFINE(CCM_CCDR, offsetof(struct mxc_ccm_reg, ccdr));
+       DEFINE(CCM_CSR, offsetof(struct mxc_ccm_reg, csr));
+       DEFINE(CCM_CCSR, offsetof(struct mxc_ccm_reg, ccsr));
+       DEFINE(CCM_CACRR, offsetof(struct mxc_ccm_reg, cacrr));
+       DEFINE(CCM_CBCDR, offsetof(struct mxc_ccm_reg, cbcdr));
+       DEFINE(CCM_CBCMR, offsetof(struct mxc_ccm_reg, cbcmr));
+       DEFINE(CCM_CSCMR1, offsetof(struct mxc_ccm_reg, cscmr1));
+       DEFINE(CCM_CSCMR2, offsetof(struct mxc_ccm_reg, cscmr2));
+       DEFINE(CCM_CSCDR1, offsetof(struct mxc_ccm_reg, cscdr1));
+       DEFINE(CCM_CS1CDR, offsetof(struct mxc_ccm_reg, cs1cdr));
+       DEFINE(CCM_CS2CDR, offsetof(struct mxc_ccm_reg, cs2cdr));
+       DEFINE(CCM_CDCDR, offsetof(struct mxc_ccm_reg, cdcdr));
+       DEFINE(CCM_CHSCCDR, offsetof(struct mxc_ccm_reg, chsccdr));
+       DEFINE(CCM_CSCDR2, offsetof(struct mxc_ccm_reg, cscdr2));
+       DEFINE(CCM_CSCDR3, offsetof(struct mxc_ccm_reg, cscdr3));
+       DEFINE(CCM_CSCDR4, offsetof(struct mxc_ccm_reg, cscdr4));
+       DEFINE(CCM_CDHIPR, offsetof(struct mxc_ccm_reg, cdhipr));
+       DEFINE(CCM_CDCR, offsetof(struct mxc_ccm_reg, cdcr));
+       DEFINE(CCM_CTOR, offsetof(struct mxc_ccm_reg, ctor));
+       DEFINE(CCM_CLPCR, offsetof(struct mxc_ccm_reg, clpcr));
+       DEFINE(CCM_CISR, offsetof(struct mxc_ccm_reg, cisr));
+       DEFINE(CCM_CIMR, offsetof(struct mxc_ccm_reg, cimr));
+       DEFINE(CCM_CCOSR, offsetof(struct mxc_ccm_reg, ccosr));
+       DEFINE(CCM_CGPR, offsetof(struct mxc_ccm_reg, cgpr));
+       DEFINE(CCM_CCGR0, offsetof(struct mxc_ccm_reg, CCGR0));
+       DEFINE(CCM_CCGR1, offsetof(struct mxc_ccm_reg, CCGR1));
+       DEFINE(CCM_CCGR2, offsetof(struct mxc_ccm_reg, CCGR2));
+       DEFINE(CCM_CCGR3, offsetof(struct mxc_ccm_reg, CCGR3));
+       DEFINE(CCM_CCGR4, offsetof(struct mxc_ccm_reg, CCGR4));
+       DEFINE(CCM_CCGR5, offsetof(struct mxc_ccm_reg, CCGR5));
+       DEFINE(CCM_CCGR6, offsetof(struct mxc_ccm_reg, CCGR6));
+       DEFINE(CCM_CCGR7, offsetof(struct mxc_ccm_reg, CCGR7));
+       DEFINE(CCM_CMEOR, offsetof(struct mxc_ccm_reg, cmeor));
+
+       DEFINE(ANATOP_PLL_ENET, offsetof(struct anatop_regs, pll_enet));
+       return 0;
+}
index 055f44e8e46c210f3bd94dba47c130185192d3be..dfd5e08a0276e3dbf7f225926dd37cc889889d02 100644 (file)
 #include <asm/arch/sys_proto.h>
 
 enum pll_clocks {
-       PLL_SYS,        /* System PLL */
-       PLL_BUS,        /* System Bus PLL*/
-       PLL_USBOTG,     /* OTG USB PLL */
-       PLL_ENET,       /* ENET PLL */
+       PLL_ARM,        /* PLL1: ARM PLL */
+       PLL_528,        /* PLL2: System Bus PLL*/
+       PLL_USBOTG,     /* PLL3: OTG USB PLL */
+       PLL_AUDIO,      /* PLL4: Audio PLL */
+       PLL_VIDEO,      /* PLL5: Video PLL */
+       PLL_ENET,       /* PLL6: ENET PLL */
+       PLL_USB2,       /* PLL7: USB2 PLL */
+       PLL_MLB,        /* PLL8: MLB PLL */
 };
 
-struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+struct mxc_ccm_reg *const imx_ccm = (void *)CCM_BASE_ADDR;
+struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
+
+int clk_enable(struct clk *clk)
+{
+       int ret = 0;
+
+       if (!clk)
+               return 0;
+       if (clk->usecount == 0) {
+               debug("%s: Enabling %s clock\n", __func__, clk->name);
+               ret = clk->enable(clk);
+               if (ret)
+                       return ret;
+               clk->usecount++;
+       }
+       assert(clk->usecount > 0);
+       return ret;
+}
+
+void clk_disable(struct clk *clk)
+{
+       if (!clk)
+               return;
+
+       assert(clk->usecount > 0);
+       if (!(--clk->usecount)) {
+               if (clk->disable) {
+                       debug("%s: Disabling %s clock\n", __func__, clk->name);
+                       clk->disable(clk);
+               }
+       }
+}
+
+int clk_get_usecount(struct clk *clk)
+{
+       if (clk == NULL)
+               return 0;
+
+       return clk->usecount;
+}
+
+u32 clk_get_rate(struct clk *clk)
+{
+       if (!clk)
+               return 0;
+
+       return clk->rate;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+       if (!clk)
+               return 0;
+
+       return clk->parent;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk && clk->set_rate)
+               clk->set_rate(clk, rate);
+       return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk == NULL || !clk->round_rate)
+               return 0;
+
+       return clk->round_rate(clk, rate);
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       debug("Setting parent of clk %p to %p (%p)\n", clk, parent,
+               clk ? clk->parent : NULL);
+
+       if (!clk || clk == parent)
+               return 0;
+
+       if (clk->set_parent) {
+               int ret;
+
+               ret = clk->set_parent(clk, parent);
+               if (ret)
+                       return ret;
+       }
+       clk->parent = parent;
+       return 0;
+}
 
 #ifdef CONFIG_MXC_OCOTP
 void enable_ocotp_clk(unsigned char enable)
@@ -184,51 +278,86 @@ static u32 decode_pll(enum pll_clocks pll, u32 infreq)
        u32 div;
 
        switch (pll) {
-       case PLL_SYS:
-               div = __raw_readl(&imx_ccm->analog_pll_sys);
-               div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
-
-               return (infreq * div) >> 1;
-       case PLL_BUS:
-               div = __raw_readl(&imx_ccm->analog_pll_528);
+       case PLL_ARM:
+               div = __raw_readl(&anatop->pll_arm);
+               if (div & BM_ANADIG_PLL_ARM_BYPASS)
+                       /* Assume the bypass clock is always derived from OSC */
+                       return infreq;
+               div &= BM_ANADIG_PLL_ARM_DIV_SELECT;
+
+               return infreq * div / 2;
+       case PLL_528:
+               div = __raw_readl(&anatop->pll_528);
+               if (div & BM_ANADIG_PLL_528_BYPASS)
+                       return infreq;
                div &= BM_ANADIG_PLL_528_DIV_SELECT;
 
-               return infreq * (20 + (div << 1));
+               return infreq * (20 + div * 2);
        case PLL_USBOTG:
-               div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl);
-               div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
-
-               return infreq * (20 + (div << 1));
+               div = __raw_readl(&anatop->usb1_pll_480_ctrl);
+               if (div & BM_ANADIG_USB_PLL_480_CTRL_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_USB_PLL_480_CTRL_DIV_SELECT;
+
+               return infreq * (20 + div * 2);
+       case PLL_AUDIO:
+               div = __raw_readl(&anatop->pll_audio);
+               if (div & BM_ANADIG_PLL_AUDIO_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT;
+
+               return infreq * div;
+       case PLL_VIDEO:
+               div = __raw_readl(&anatop->pll_video);
+               if (div & BM_ANADIG_PLL_VIDEO_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT;
+
+               return infreq * div;
        case PLL_ENET:
-               div = __raw_readl(&imx_ccm->analog_pll_enet);
+               div = __raw_readl(&anatop->pll_enet);
+               if (div & BM_ANADIG_PLL_ENET_BYPASS)
+                       return infreq;
                div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
 
                return 25000000 * (div + (div >> 1) + 1);
-       default:
+       case PLL_USB2:
+               div = __raw_readl(&anatop->usb2_pll_480_ctrl);
+               if (div & BM_ANADIG_USB_PLL_480_CTRL_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_USB_PLL_480_CTRL_DIV_SELECT;
+
+               return infreq * (20 + div * 2);
+       case PLL_MLB:
+               div = __raw_readl(&anatop->pll_mlb);
+               if (div & BM_ANADIG_PLL_MLB_BYPASS)
+                       return infreq;
+               /* unknown external clock provided on MLB_CLK pin */
                return 0;
        }
-       /* NOTREACHED */
+       return 0;
 }
 static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num)
 {
        u32 div;
        u64 freq;
+       struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 
        switch (pll) {
-       case PLL_BUS:
+       case PLL_528:
                if (pfd_num == 3) {
-                       /* No PFD3 on PPL2 */
+                       /* No PFD3 on PLL2 */
                        return 0;
                }
-               div = __raw_readl(&imx_ccm->analog_pfd_528);
-               freq = (u64)decode_pll(PLL_BUS, MXC_HCLK);
+               div = __raw_readl(&anatop->pfd_528);
+               freq = (u64)decode_pll(PLL_528, MXC_HCLK);
                break;
        case PLL_USBOTG:
-               div = __raw_readl(&imx_ccm->analog_pfd_480);
+               div = __raw_readl(&anatop->pfd_480);
                freq = (u64)decode_pll(PLL_USBOTG, MXC_HCLK);
                break;
        default:
-               /* No PFD on other PLL                                       */
+               /* No PFD on other PLL */
                return 0;
        }
 
@@ -243,7 +372,7 @@ static u32 get_mcu_main_clk(void)
        reg = __raw_readl(&imx_ccm->cacrr);
        reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
        reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
-       freq = decode_pll(PLL_SYS, MXC_HCLK);
+       freq = decode_pll(PLL_ARM, MXC_HCLK);
 
        return freq / (reg + 1);
 }
@@ -266,8 +395,6 @@ u32 get_periph_clk(void)
                case 2:
                        freq = MXC_HCLK;
                        break;
-               default:
-                       break;
                }
        } else {
                reg = __raw_readl(&imx_ccm->cbcmr);
@@ -276,19 +403,17 @@ u32 get_periph_clk(void)
 
                switch (reg) {
                case 0:
-                       freq = decode_pll(PLL_BUS, MXC_HCLK);
+                       freq = decode_pll(PLL_528, MXC_HCLK);
                        break;
                case 1:
-                       freq = mxc_get_pll_pfd(PLL_BUS, 2);
+                       freq = mxc_get_pll_pfd(PLL_528, 2);
                        break;
                case 2:
-                       freq = mxc_get_pll_pfd(PLL_BUS, 0);
+                       freq = mxc_get_pll_pfd(PLL_528, 0);
                        break;
                case 3:
                        /* static / 2 divider */
-                       freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2;
-                       break;
-               default:
+                       freq = mxc_get_pll_pfd(PLL_528, 2) / 2;
                        break;
                }
        }
@@ -357,7 +482,7 @@ static u32 get_axi_clk(void)
 
        if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
                if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
-                       root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
+                       root_freq = mxc_get_pll_pfd(PLL_528, 2);
                else
                        root_freq = mxc_get_pll_pfd(PLL_USBOTG, 1);
        } else
@@ -384,16 +509,114 @@ static u32 get_emi_slow_clk(void)
                root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
                break;
        case 2:
-               root_freq =  mxc_get_pll_pfd(PLL_BUS, 2);
+               root_freq =  mxc_get_pll_pfd(PLL_528, 2);
                break;
        case 3:
-               root_freq =  mxc_get_pll_pfd(PLL_BUS, 0);
+               root_freq =  mxc_get_pll_pfd(PLL_528, 0);
                break;
        }
 
        return root_freq / (emi_slow_podf + 1);
 }
 
+static u32 get_nfc_clk(void)
+{
+       u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
+       u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
+       u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
+       int nfc_clk_sel = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >>
+               MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
+       u32 root_freq;
+
+       switch (nfc_clk_sel) {
+       case 0:
+               root_freq = mxc_get_pll_pfd(PLL_528, 0);
+               break;
+       case 1:
+               root_freq = decode_pll(PLL_528, MXC_HCLK);
+               break;
+       case 2:
+               root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
+               break;
+       case 3:
+               root_freq = mxc_get_pll_pfd(PLL_528, 2);
+               break;
+       }
+
+       return root_freq / (pred + 1) / (podf + 1);
+}
+
+#define CS2CDR_ENFC_MASK       (MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |    \
+                               MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |     \
+                               MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK)
+
+static int set_nfc_clk(u32 ref, u32 freq_khz)
+{
+       u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
+       u32 podf;
+       u32 pred;
+       int nfc_clk_sel;
+       u32 root_freq;
+       u32 min_err = ~0;
+       u32 nfc_val = ~0;
+       u32 freq = freq_khz * 1000;
+
+       for (nfc_clk_sel = 0; nfc_clk_sel < 4; nfc_clk_sel++) {
+               u32 act_freq;
+               u32 err;
+
+               if (ref < 4 && ref != nfc_clk_sel)
+                       continue;
+
+               switch (nfc_clk_sel) {
+               case 0:
+                       root_freq = mxc_get_pll_pfd(PLL_528, 0);
+                       break;
+               case 1:
+                       root_freq = decode_pll(PLL_528, MXC_HCLK);
+                       break;
+               case 2:
+                       root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
+                       break;
+               case 3:
+                       root_freq = mxc_get_pll_pfd(PLL_528, 2);
+                       break;
+               }
+               if (root_freq < freq)
+                       continue;
+
+               podf = min(DIV_ROUND_UP(root_freq, freq), 1U << 6);
+               pred = min(DIV_ROUND_UP(root_freq / podf, freq), 8U);
+               act_freq = root_freq / pred / podf;
+               err = (freq - act_freq) * 100 / freq;
+               debug("root=%d[%u] freq=%u pred=%u podf=%u act=%u err=%d\n",
+                       nfc_clk_sel, root_freq, freq, pred, podf, act_freq, err);
+               if (act_freq > freq)
+                       continue;
+               if (err < min_err) {
+                       nfc_val = (podf - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
+                       nfc_val |= (pred - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
+                       nfc_val |= nfc_clk_sel << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
+                       min_err = err;
+                       if (err == 0)
+                               break;
+               }
+       }
+
+       if (nfc_val == ~0 || min_err > 10)
+               return -EINVAL;
+
+       if ((cs2cdr & CS2CDR_ENFC_MASK) != nfc_val) {
+               debug("changing cs2cdr from %08x to %08x\n", cs2cdr,
+                       (cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val);
+               __raw_writel((cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val,
+                       &imx_ccm->cs2cdr);
+       } else {
+               debug("Leaving cs2cdr unchanged [%08x]\n", cs2cdr);
+       }
+       return 0;
+}
+
 #if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
 static u32 get_mmdc_ch0_clk(void)
 {
@@ -407,17 +630,17 @@ static u32 get_mmdc_ch0_clk(void)
        switch ((cbcmr & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >>
                MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) {
        case 0:
-               freq = decode_pll(PLL_BUS, MXC_HCLK);
+               freq = decode_pll(PLL_528, MXC_HCLK);
                break;
        case 1:
-               freq = mxc_get_pll_pfd(PLL_BUS, 2);
+               freq = mxc_get_pll_pfd(PLL_528, 2);
                break;
        case 2:
-               freq = mxc_get_pll_pfd(PLL_BUS, 0);
+               freq = mxc_get_pll_pfd(PLL_528, 0);
                break;
        case 3:
                /* static / 2 divider */
-               freq =  mxc_get_pll_pfd(PLL_BUS, 2) / 2;
+               freq =  mxc_get_pll_pfd(PLL_528, 2) / 2;
        }
 
        return freq / (podf + 1);
@@ -578,9 +801,9 @@ static u32 get_usdhc_clk(u32 port)
        }
 
        if (clk_sel)
-               root_freq = mxc_get_pll_pfd(PLL_BUS, 0);
+               root_freq = mxc_get_pll_pfd(PLL_528, 0);
        else
-               root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
+               root_freq = mxc_get_pll_pfd(PLL_528, 2);
 
        return root_freq / (usdhc_podf + 1);
 }
@@ -597,26 +820,24 @@ u32 imx_get_fecclk(void)
 
 static int enable_enet_pll(uint32_t en)
 {
-       struct mxc_ccm_reg *const imx_ccm
-               = (struct mxc_ccm_reg *) CCM_BASE_ADDR;
+       u32 reg;
        s32 timeout = 100000;
-       u32 reg = 0;
 
        /* Enable PLLs */
-       reg = readl(&imx_ccm->analog_pll_enet);
-       reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN;
-       writel(reg, &imx_ccm->analog_pll_enet);
-       reg |= BM_ANADIG_PLL_SYS_ENABLE;
+       reg = readl(&anatop->pll_enet);
+       reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
+       writel(reg, &anatop->pll_enet);
+       reg |= BM_ANADIG_PLL_ENET_ENABLE;
        while (timeout--) {
-               if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK)
+               if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
                        break;
        }
        if (timeout <= 0)
                return -EIO;
-       reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
-       writel(reg, &imx_ccm->analog_pll_enet);
+       reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
+       writel(reg, &anatop->pll_enet);
        reg |= en;
-       writel(reg, &imx_ccm->analog_pll_enet);
+       writel(reg, &anatop->pll_enet);
        return 0;
 }
 
@@ -738,20 +959,20 @@ static void enable_pll3(void)
 
        /* make sure pll3 is enabled */
        if ((readl(&anatop->usb1_pll_480_ctrl) &
-                       BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) {
+                       BM_ANADIG_USB_PLL_480_CTRL_LOCK) == 0) {
                /* enable pll's power */
-               writel(BM_ANADIG_USB1_PLL_480_CTRL_POWER,
+               writel(BM_ANADIG_USB_PLL_480_CTRL_POWER,
                       &anatop->usb1_pll_480_ctrl_set);
                writel(0x80, &anatop->ana_misc2_clr);
                /* wait for pll lock */
                while ((readl(&anatop->usb1_pll_480_ctrl) &
-                       BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0)
+                       BM_ANADIG_USB_PLL_480_CTRL_LOCK) == 0)
                        ;
                /* disable bypass */
-               writel(BM_ANADIG_USB1_PLL_480_CTRL_BYPASS,
+               writel(BM_ANADIG_USB_PLL_480_CTRL_BYPASS,
                       &anatop->usb1_pll_480_ctrl_clr);
                /* enable pll output */
-               writel(BM_ANADIG_USB1_PLL_480_CTRL_ENABLE,
+               writel(BM_ANADIG_USB_PLL_480_CTRL_ENABLE,
                       &anatop->usb1_pll_480_ctrl_set);
        }
 }
@@ -761,6 +982,98 @@ void enable_thermal_clk(void)
        enable_pll3();
 }
 
+void ipu_clk_enable(void)
+{
+       u32 reg = readl(&imx_ccm->CCGR3);
+       reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK;
+       writel(reg, &imx_ccm->CCGR3);
+}
+
+void ipu_clk_disable(void)
+{
+       u32 reg = readl(&imx_ccm->CCGR3);
+       reg &= ~MXC_CCM_CCGR3_IPU1_IPU_MASK;
+       writel(reg, &imx_ccm->CCGR3);
+}
+
+void ipu_di_clk_enable(int di)
+{
+       switch (di) {
+       case 0:
+               setbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
+               break;
+       case 1:
+               setbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_IPU1_IPU_DI1_MASK);
+               break;
+       default:
+               printf("%s: Invalid DI index %d\n", __func__, di);
+       }
+}
+
+void ipu_di_clk_disable(int di)
+{
+       switch (di) {
+       case 0:
+               clrbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
+               break;
+       case 1:
+               clrbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_IPU1_IPU_DI1_MASK);
+               break;
+       default:
+               printf("%s: Invalid DI index %d\n", __func__, di);
+       }
+}
+
+void ldb_clk_enable(int ldb)
+{
+       switch (ldb) {
+       case 0:
+               setbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_LDB_DI0_MASK);
+               break;
+       case 1:
+               setbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_LDB_DI1_MASK);
+               break;
+       default:
+               printf("%s: Invalid LDB index %d\n", __func__, ldb);
+       }
+}
+
+void ldb_clk_disable(int ldb)
+{
+       switch (ldb) {
+       case 0:
+               clrbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_LDB_DI0_MASK);
+               break;
+       case 1:
+               clrbits_le32(&imx_ccm->CCGR3,
+                       MXC_CCM_CCGR3_LDB_DI1_MASK);
+               break;
+       default:
+               printf("%s: Invalid LDB index %d\n", __func__, ldb);
+       }
+}
+
+void ocotp_clk_enable(void)
+{
+       u32 reg = readl(&imx_ccm->CCGR2);
+       reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
+       writel(reg, &imx_ccm->CCGR2);
+}
+
+void ocotp_clk_disable(void)
+{
+       u32 reg = readl(&imx_ccm->CCGR2);
+       reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
+       writel(reg, &imx_ccm->CCGR2);
+}
+
 unsigned int mxc_get_clock(enum mxc_clock clk)
 {
        switch (clk) {
@@ -795,46 +1108,275 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
                return get_usdhc_clk(3);
        case MXC_SATA_CLK:
                return get_ahb_clk();
+       case MXC_NFC_CLK:
+               return get_nfc_clk();
        default:
                printf("Unsupported MXC CLK: %d\n", clk);
-               break;
        }
 
        return 0;
 }
 
+static inline int gcd(int m, int n)
+{
+       int t;
+       while (m > 0) {
+               if (n > m) {
+                       t = m;
+                       m = n;
+                       n = t;
+               } /* swap */
+               m -= n;
+       }
+       return n;
+}
+
+/* Config CPU clock */
+static int set_arm_clk(u32 ref, u32 freq_khz)
+{
+       int d;
+       int div = 0;
+       int mul = 0;
+       u32 min_err = ~0;
+       u32 reg;
+
+       if (freq_khz > ref / 1000 * 108 / 2 || freq_khz < ref / 1000 * 54 / 8 / 2) {
+               printf("Frequency %u.%03uMHz is out of range: %u.%03u..%u.%03u\n",
+                       freq_khz / 1000, freq_khz % 1000,
+                       54 * ref / 1000000 / 8 / 2, 54 * ref / 1000 / 8 / 2 % 1000,
+                       108 * ref / 1000000 / 2, 108 * ref / 1000 / 2 % 1000);
+               return -EINVAL;
+       }
+
+       for (d = DIV_ROUND_UP(648000, freq_khz); d <= 8; d++) {
+               int m = freq_khz * 2 * d / (ref / 1000);
+               u32 f;
+               u32 err;
+
+               if (m > 108) {
+                       debug("%s@%d: d=%d m=%d\n", __func__, __LINE__,
+                               d, m);
+                       break;
+               }
+
+               f = ref * m / d / 2;
+               if (f > freq_khz * 1000) {
+                       debug("%s@%d: d=%d m=%d f=%u freq=%u\n", __func__, __LINE__,
+                               d, m, f, freq_khz);
+                       if (--m < 54)
+                               return -EINVAL;
+                       f = ref * m / d / 2;
+               }
+               err = freq_khz * 1000 - f;
+               debug("%s@%d: d=%d m=%d f=%u freq=%u err=%d\n", __func__, __LINE__,
+                       d, m, f, freq_khz, err);
+               if (err < min_err) {
+                       mul = m;
+                       div = d;
+                       min_err = err;
+                       if (err == 0)
+                               break;
+               }
+       }
+       if (min_err == ~0)
+               return -EINVAL;
+       debug("Setting M=%3u D=%2u for %u.%03uMHz (actual: %u.%03uMHz)\n",
+               mul, div, freq_khz / 1000, freq_khz % 1000,
+               ref * mul / 2 / div / 1000000, ref * mul / 2 / div / 1000 % 1000);
+
+       reg = readl(&anatop->pll_arm);
+       debug("anadig_pll_arm=%08x -> %08x\n",
+               reg, (reg & ~0x7f) | mul);
+
+       reg |= 1 << 16;
+       writel(reg, &anatop->pll_arm); /* bypass PLL */
+
+       reg = (reg & ~0x7f) | mul;
+       writel(reg, &anatop->pll_arm);
+
+       writel(div - 1, &imx_ccm->cacrr);
+
+       reg &= ~(1 << 16);
+       writel(reg, &anatop->pll_arm); /* disable PLL bypass */
+
+       return 0;
+}
+
 /*
- * Dump some core clockes.
+ * This function assumes the expected core clock has to be changed by
+ * modifying the PLL. This is NOT true always but for most of the times,
+ * it is. So it assumes the PLL output freq is the same as the expected
+ * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
+ * In the latter case, it will try to increase the presc value until
+ * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
+ * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
+ * on the targeted PLL and reference input clock to the PLL. Lastly,
+ * it sets the register based on these values along with the dividers.
+ * Note 1) There is no value checking for the passed-in divider values
+ *         so the caller has to make sure those values are sensible.
+ *      2) Also adjust the NFC divider such that the NFC clock doesn't
+ *         exceed NFC_CLK_MAX.
+ *      3) IPU HSP clock is independent of AHB clock. Even it can go up to
+ *         177MHz for higher voltage, this function fixes the max to 133MHz.
+ *      4) This function should not have allowed diag_printf() calls since
+ *         the serial driver has been stoped. But leave then here to allow
+ *         easy debugging by NOT calling the cyg_hal_plf_serial_stop().
  */
-int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       u32 freq;
-       freq = decode_pll(PLL_SYS, MXC_HCLK);
-       printf("PLL_SYS    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_BUS, MXC_HCLK);
-       printf("PLL_BUS    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_USBOTG, MXC_HCLK);
-       printf("PLL_OTG    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_ENET, MXC_HCLK);
-       printf("PLL_NET    %8d MHz\n", freq / 1000000);
+int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
+{
+       int ret;
+
+       freq *= 1000;
+
+       switch (clk) {
+       case MXC_ARM_CLK:
+               ret = set_arm_clk(ref, freq);
+               break;
+
+       case MXC_NFC_CLK:
+               ret = set_nfc_clk(ref, freq);
+               break;
+
+       default:
+               printf("Warning: Unsupported or invalid clock type: %d\n",
+                       clk);
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
+/*
+ * Dump some core clocks.
+ */
+#define print_pll(pll) {                               \
+       u32 __pll = decode_pll(pll, MXC_HCLK);          \
+       printf("%-12s %4d.%03d MHz\n", #pll,            \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+
+#define MXC_IPG_PER_CLK        MXC_IPG_PERCLK
 
+#define print_clk(clk) {                               \
+       u32 __clk = mxc_get_clock(MXC_##clk##_CLK);     \
+       printf("%-12s %4d.%03d MHz\n", #clk,            \
+               __clk / 1000000, __clk / 1000 % 1000);  \
+       }
+
+#define print_pfd(pll, pfd)    {                                       \
+       u32 __pfd = readl(&anatop->pfd_##pll);                          \
+       if (__pfd & (0x80 << 8 * pfd)) {                                \
+               printf("PFD_%s[%d]      OFF\n", #pll, pfd);             \
+       } else {                                                        \
+               __pfd = (__pfd >> 8 * pfd) & 0x3f;                      \
+               printf("PFD_%s[%d]   %4d.%03d MHz\n", #pll, pfd,        \
+                       pll * 18 / __pfd,                               \
+                       pll * 18 * 1000 / __pfd % 1000);                \
+       }                                                               \
+}
+
+static void do_mx6_showclocks(void)
+{
+       print_pll(PLL_ARM);
+       print_pll(PLL_528);
+       print_pll(PLL_USBOTG);
+       print_pll(PLL_AUDIO);
+       print_pll(PLL_VIDEO);
+       print_pll(PLL_ENET);
+       print_pll(PLL_USB2);
        printf("\n");
-       printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
-       printf("UART       %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000);
-#ifdef CONFIG_MXC_SPI
-       printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
-#endif
-       printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
-       printf("AXI        %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000);
-       printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
-       printf("USDHC1     %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000);
-       printf("USDHC2     %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000);
-       printf("USDHC3     %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000);
-       printf("USDHC4     %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000);
-       printf("EMI SLOW   %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000);
-       printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
 
-       return 0;
+       print_pfd(480, 0);
+       print_pfd(480, 1);
+       print_pfd(480, 2);
+       print_pfd(480, 3);
+       print_pfd(528, 0);
+       print_pfd(528, 1);
+       print_pfd(528, 2);
+       printf("\n");
+
+       print_clk(IPG);
+       print_clk(UART);
+       print_clk(CSPI);
+       print_clk(AHB);
+       print_clk(AXI);
+       print_clk(DDR);
+       print_clk(ESDHC);
+       print_clk(ESDHC2);
+       print_clk(ESDHC3);
+       print_clk(ESDHC4);
+       print_clk(EMI_SLOW);
+       print_clk(NFC);
+       print_clk(IPG_PER);
+       print_clk(ARM);
+}
+
+static struct clk_lookup {
+       const char *name;
+       unsigned int index;
+} mx6_clk_lookup[] = {
+       { "arm", MXC_ARM_CLK, },
+       { "nfc", MXC_NFC_CLK, },
+};
+
+int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int i;
+       unsigned long freq;
+       unsigned long ref = ~0UL;
+
+       if (argc < 2) {
+               do_mx6_showclocks();
+               return CMD_RET_SUCCESS;
+       } else if (argc == 2 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+
+       freq = simple_strtoul(argv[2], NULL, 0);
+       if (freq == 0) {
+               printf("Invalid clock frequency %lu\n", freq);
+               return CMD_RET_FAILURE;
+       }
+       if (argc > 3) {
+               ref = simple_strtoul(argv[3], NULL, 0);
+       }
+       for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
+               if (strcasecmp(argv[1], mx6_clk_lookup[i].name) == 0) {
+                       switch (mx6_clk_lookup[i].index) {
+                       case MXC_ARM_CLK:
+                               if (argc > 3)
+                                       return CMD_RET_USAGE;
+                               ref = MXC_HCLK;
+                               break;
+
+                       case MXC_NFC_CLK:
+                               if (argc > 3 && ref > 3) {
+                                       printf("Invalid clock selector value: %lu\n", ref);
+                                       return CMD_RET_FAILURE;
+                               }
+                               break;
+                       }
+                       printf("Setting %s clock to %lu MHz\n",
+                               mx6_clk_lookup[i].name, freq);
+                       if (mxc_set_clock(ref, freq, mx6_clk_lookup[i].index))
+                               break;
+                       freq = mxc_get_clock(mx6_clk_lookup[i].index);
+                       printf("%s clock set to %lu.%03lu MHz\n",
+                               mx6_clk_lookup[i].name,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return CMD_RET_SUCCESS;
+               }
+       }
+       if (i == ARRAY_SIZE(mx6_clk_lookup)) {
+               printf("clock %s not found; supported clocks are:\n", argv[1]);
+               for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
+                       printf("\t%s\n", mx6_clk_lookup[i].name);
+               }
+       } else {
+               printf("Failed to set clock %s to %s MHz\n",
+                       argv[1], argv[2]);
+       }
+       return CMD_RET_FAILURE;
 }
 
 #ifndef CONFIG_MX6SX
@@ -850,7 +1392,8 @@ void enable_ipu_clock(void)
 /***************************************************/
 
 U_BOOT_CMD(
-       clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks,
-       "display clocks",
-       ""
+       clocks, 4, 0, do_clocks,
+       "display/set clocks",
+       "                    - display clock settings\n"
+       "clocks <clkname> <freq>    - set clock <clkname> to <freq> MHz"
 );
index 5f5f49720107f56717e676eafbfd94983ffee9b4..5cf472d24f3393ea8aa8e0bdfb17f27230983529 100644 (file)
@@ -14,6 +14,8 @@
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/regs-ocotp.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/imx-common/boot_mode.h>
 #include <asm/bootm.h>
 #include <dm.h>
 #include <imx_thermal.h>
+#include <div64.h>
+#include <ipu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define __data __attribute__((section(".data")))
+
+#ifdef CONFIG_MX6_TEMPERATURE_MIN
+#define TEMPERATURE_MIN                        CONFIG_MX6_TEMPERATURE_MIN
+#else
+#define TEMPERATURE_MIN                        (-40)
+#endif
+#ifdef CONFIG_MX6_TEMPERATURE_HOT
+#define TEMPERATURE_HOT                        CONFIG_MX6_TEMPERATURE_HOT
+#else
+#define TEMPERATURE_HOT                        80
+#endif
+#ifdef CONFIG_MX6_TEMPERATURE_MAX
+#define TEMPERATURE_MAX                        CONFIG_MX6_TEMPERATURE_MAX
+#else
+#define TEMPERATURE_MAX                        125
+#endif
+#define TEMP_AVG_COUNT                 5
+#define TEMP_WARN_THRESHOLD            5
 
 enum ldo_reg {
        LDO_ARM,
@@ -225,6 +251,177 @@ static int set_ldo_voltage(enum ldo_reg ldo, u32 mv)
        return 0;
 }
 
+static u32 __data thermal_calib;
+
+#define FACTOR0                                10000000
+#define FACTOR1                                15976
+#define FACTOR2                                4297157
+
+int raw_to_celsius(unsigned int raw, unsigned int raw_25c, unsigned int raw_hot,
+               unsigned int hot_temp)
+{
+       int temperature;
+
+       if (raw_hot != 0 && hot_temp != 0) {
+               unsigned int raw_n40c, ratio;
+
+               ratio = ((raw_25c - raw_hot) * 100) / (hot_temp - 25);
+               raw_n40c = raw_25c + (13 * ratio) / 20;
+               if (raw <= raw_n40c)
+                       temperature = (raw_n40c - raw) * 100 / ratio - 40;
+               else
+                       temperature = TEMPERATURE_MIN;
+       } else {
+               u64 temp64 = FACTOR0;
+               unsigned int c1, c2;
+               /*
+                * Derived from linear interpolation:
+                * slope = 0.4297157 - (0.0015976 * 25C fuse)
+                * slope = (FACTOR2 - FACTOR1 * n1) / FACTOR0
+                * (Nmeas - n1) / (Tmeas - t1) = slope
+                * We want to reduce this down to the minimum computation necessary
+                * for each temperature read.  Also, we want Tmeas in millicelsius
+                * and we don't want to lose precision from integer division. So...
+                * Tmeas = (Nmeas - n1) / slope + t1
+                * milli_Tmeas = 1000 * (Nmeas - n1) / slope + 1000 * t1
+                * milli_Tmeas = -1000 * (n1 - Nmeas) / slope + 1000 * t1
+                * Let constant c1 = (-1000 / slope)
+                * milli_Tmeas = (n1 - Nmeas) * c1 + 1000 * t1
+                * Let constant c2 = n1 *c1 + 1000 * t1
+                * milli_Tmeas = c2 - Nmeas * c1
+                */
+               temp64 *= 1000;
+               do_div(temp64, FACTOR1 * raw_25c - FACTOR2);
+               c1 = temp64;
+               c2 = raw_25c * c1 + 1000 * 25;
+               temperature = (c2 - raw * c1) / 1000;
+       }
+       return temperature;
+}
+
+int read_cpu_temperature(void)
+{
+       unsigned int reg, tmp, i;
+       unsigned int raw_25c, raw_hot, hot_temp;
+       int temperature;
+       struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
+       struct mx6_ocotp_regs *const ocotp_regs = (void *)OCOTP_BASE_ADDR;
+
+       if (!thermal_calib) {
+               ocotp_clk_enable();
+               writel(1, &ocotp_regs->hw_ocotp_read_ctrl);
+               thermal_calib = readl(&ocotp_regs->hw_ocotp_ana1);
+               writel(0, &ocotp_regs->hw_ocotp_read_ctrl);
+               ocotp_clk_disable();
+       }
+
+       if (thermal_calib == 0 || thermal_calib == 0xffffffff)
+               return TEMPERATURE_MIN;
+
+       /* Fuse data layout:
+        * [31:20] sensor value @ 25C
+        * [19:8] sensor value of hot
+        * [7:0] hot temperature value */
+       raw_25c = thermal_calib >> 20;
+       raw_hot = (thermal_calib & 0xfff00) >> 8;
+       hot_temp = thermal_calib & 0xff;
+
+       /* now we only using single measure, every time we measure
+        * the temperature, we will power on/off the anadig module
+        */
+       writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
+
+       /* write measure freq */
+       writel(327, &anatop->tempsense1);
+       writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_set);
+
+       /* average the temperature value over multiple readings */
+       for (i = 0; i < TEMP_AVG_COUNT; i++) {
+               static int failed;
+               int limit = 100;
+
+               while ((readl(&anatop->tempsense0) &
+                               BM_ANADIG_TEMPSENSE0_FINISHED) == 0) {
+                       udelay(10000);
+                       if (--limit < 0)
+                               break;
+               }
+               if ((readl(&anatop->tempsense0) &
+                               BM_ANADIG_TEMPSENSE0_FINISHED) == 0) {
+                       if (!failed) {
+                               printf("Failed to read temp sensor\n");
+                               failed = 1;
+                       }
+                       return 0;
+               }
+               failed = 0;
+               reg = (readl(&anatop->tempsense0) &
+                       BM_ANADIG_TEMPSENSE0_TEMP_VALUE) >>
+                       BP_ANADIG_TEMPSENSE0_TEMP_VALUE;
+               if (i == 0)
+                       tmp = reg;
+               else
+                       tmp = (tmp * i + reg) / (i + 1);
+               writel(BM_ANADIG_TEMPSENSE0_FINISHED,
+                       &anatop->tempsense0_clr);
+       }
+
+       temperature = raw_to_celsius(tmp, raw_25c, raw_hot, hot_temp);
+
+       /* power down anatop thermal sensor */
+       writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set);
+       writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_clr);
+
+       return temperature;
+}
+
+int check_cpu_temperature(int boot)
+{
+       static int __data max_temp;
+       int boot_limit = getenv_ulong("max_boot_temp", 10, TEMPERATURE_HOT);
+       int tmp = read_cpu_temperature();
+       bool first = true;
+
+       if (tmp < TEMPERATURE_MIN || tmp > TEMPERATURE_MAX) {
+               printf("Temperature:   can't get valid data!\n");
+               return tmp;
+       }
+
+       if (!boot) {
+               if (tmp > boot_limit) {
+                       printf("CPU is %d C, too hot, resetting...\n", tmp);
+                       udelay(100000);
+                       reset_cpu(0);
+               }
+               if (tmp > max_temp) {
+                       if (tmp > boot_limit - TEMP_WARN_THRESHOLD)
+                               printf("WARNING: CPU temperature %d C\n", tmp);
+                       max_temp = tmp;
+               }
+       } else {
+               printf("Temperature:   %d C, calibration data 0x%x\n",
+                       tmp, thermal_calib);
+               while (tmp >= boot_limit) {
+                       if (first) {
+                               printf("CPU is %d C, too hot to boot, waiting...\n",
+                                       tmp);
+                               first = false;
+                       }
+                       if (ctrlc())
+                               break;
+                       udelay(50000);
+                       tmp = read_cpu_temperature();
+                       if (tmp > boot_limit - TEMP_WARN_THRESHOLD && tmp != max_temp)
+                               printf("WARNING: CPU temperature %d C\n", tmp);
+                       max_temp = tmp;
+               }
+       }
+       return tmp;
+}
+
 static void imx_set_wdog_powerdown(bool enable)
 {
        struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
@@ -289,8 +486,12 @@ int arch_cpu_init(void)
 
        imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
 
-#ifdef CONFIG_APBH_DMA
-       /* Start APBH DMA */
+#ifdef CONFIG_VIDEO_IPUV3
+       gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3H;
+#endif
+#ifdef  CONFIG_APBH_DMA
+       /* Timer is required for Initializing APBH DMA */
+       timer_init();
        mxs_dma_init();
 #endif
 
@@ -339,14 +540,13 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 
        u32 value = readl(&fuse->mac_addr_high);
        mac[0] = (value >> 8);
-       mac[1] = value ;
+       mac[1] = value;
 
        value = readl(&fuse->mac_addr_low);
-       mac[2] = value >> 24 ;
-       mac[3] = value >> 16 ;
-       mac[4] = value >> 8 ;
-       mac[5] = value ;
-
+       mac[2] = value >> 24;
+       mac[3] = value >> 16;
+       mac[4] = value >> 8;
+       mac[5] = value;
 }
 #endif
 
index 17500f2315ee9d3d5a8a5868c3e3e75f46a7148b..ab4a070f97007bf5d308ad8cc19395ea8282c9ef 100644 (file)
@@ -85,7 +85,7 @@ void save_omap_boot_params(void)
 #ifdef CONFIG_SPL_BUILD
 u32 spl_boot_device(void)
 {
-       return (u32) (gd->arch.omap_boot_params.omap_bootdevice);
+       return gd->arch.omap_boot_params.omap_bootdevice;
 }
 
 u32 spl_boot_mode(void)
index 86c0e4217478f9d06b00723d7280c6629e465059..9c8cf89aa6cccaba31ef48bd3038b076c895ce48 100644 (file)
@@ -26,7 +26,11 @@ ENTRY(set_pl310_ctrl_reg)
        PUSH    {r4-r11, lr}    @ save registers - ROM code may pollute
                                @ our registers
        LDR     r12, =0x102     @ Set PL310 control register - value in R0
-       .word   0xe1600070      @ SMC #0 - hand assembled because -march=armv5
-                               @ call ROM Code API to set control register
+#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 && defined(__ARM_ARCH_7A__)
+       .arch_extension sec
+       smc     #0              @ call ROM Code API to set control register
+#else
+       .word   0xe1600070
+#endif
        POP     {r4-r11, pc}
 ENDPROC(set_pl310_ctrl_reg)
index 91ad031ddd33a035ded80d3b3406132a6e096044..4145e37c3f52c96cc7e254fe9305c9d3a03bc891 100644 (file)
@@ -9,6 +9,7 @@
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
+#include <common.h>
 #include <config.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
@@ -16,6 +17,8 @@
 
 void __weak reset_cpu(unsigned long ignored)
 {
+       /* clear the reset status flags */
+       writel(readl(PRM_RSTST), PRM_RSTST);
        writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
 }
 
index 032bd2c24fdddb95705096ddc94c692f6b2fa735..152995aac5ed828f22864643f696842c3f441652 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <common.h>
+#include <div64.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/clock.h>
@@ -29,17 +30,67 @@ static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
  * Nothing really to do with interrupts, just starts up a counter.
  */
 
+#if CONFIG_SYS_PTV > 7
+#error Invalid CONFIG_SYS_PTV value
+#elif CONFIG_SYS_PTV >= 0
 #define TIMER_CLOCK            (V_SCLK / (2 << CONFIG_SYS_PTV))
-#define TIMER_OVERFLOW_VAL     0xffffffff
+#define TCLR_VAL               ((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST)
+#else
+#define TIMER_CLOCK            V_SCLK
+#define TCLR_VAL               (TCLR_AR | TCLR_ST)
+#endif
 #define TIMER_LOAD_VAL         0
 
+#define TIOCP_CFG_SOFTRESET    (1 << 0)
+
+#if TIMER_CLOCK < CONFIG_SYS_HZ
+#error TIMER_CLOCK must be >= CONFIG_SYS_HZ
+#endif
+
+/*
+ * Start timer so that it will overflow 15 sec after boot,
+ * to catch misbehaving timer code early on!
+*/
+#define TIMER_START            (-time_to_tick(15 * CONFIG_SYS_HZ))
+
+static inline unsigned long tick_to_time(unsigned long tick)
+{
+       return tick / (TIMER_CLOCK / CONFIG_SYS_HZ);
+}
+
+static inline unsigned long time_to_tick(unsigned long time)
+{
+       return time * (TIMER_CLOCK / CONFIG_SYS_HZ);
+}
+
+static inline unsigned long us_to_ticks(unsigned long usec)
+{
+       return usec * (TIMER_CLOCK / CONFIG_SYS_HZ / 1000);
+}
+
 int timer_init(void)
 {
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+       /* Reset the Timer */
+       writel(TIOCP_CFG_SOFTRESET, &timer_base->tiocp_cfg);
+
+       /* Wait until the reset is done */
+       while (readl(&timer_base->tiocp_cfg) & TIOCP_CFG_SOFTRESET)
+               ;
+
+       /* preload the counter to make overflow occur early */
+       writel(TIMER_START, &timer_base->tldr);
+       writel(~0, &timer_base->ttgr);
+
        /* start the counter ticking up, reload value on overflow */
        writel(TIMER_LOAD_VAL, &timer_base->tldr);
        /* enable timer */
-       writel((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST,
-               &timer_base->tclr);
+       writel(TCLR_VAL, &timer_base->tclr);
+#endif
+       gd->arch.lastinc = -30 * TIMER_CLOCK;
+       gd->arch.tbl = TIMER_START;
+       gd->arch.tbu = 0;
+       gd->arch.timer_rate_hz = TIMER_CLOCK;
 
        return 0;
 }
@@ -49,39 +100,29 @@ int timer_init(void)
  */
 ulong get_timer(ulong base)
 {
-       return get_timer_masked() - base;
+       return tick_to_time(get_ticks() - time_to_tick(base));
 }
 
 /* delay x useconds */
 void __udelay(unsigned long usec)
 {
-       long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
-       unsigned long now, last = readl(&timer_base->tcrr);
-
-       while (tmo > 0) {
-               now = readl(&timer_base->tcrr);
-               if (last > now) /* count up timer overflow */
-                       tmo -= TIMER_OVERFLOW_VAL - last + now + 1;
-               else
-                       tmo -= now - last;
-               last = now;
-       }
+       unsigned long start = readl(&timer_base->tcrr);
+       unsigned long ticks = us_to_ticks(usec);
+
+       if (usec == 0)
+               return;
+
+       if (ticks == 0)
+               ticks++;
+
+       while (readl(&timer_base->tcrr) - start < ticks)
+               /* NOP */ ;
 }
 
 ulong get_timer_masked(void)
 {
        /* current tick value */
-       ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-
-       if (now >= gd->arch.lastinc) {  /* normal mode (non roll) */
-               /* move stamp fordward with absoulte diff ticks */
-               gd->arch.tbl += (now - gd->arch.lastinc);
-       } else {        /* we have rollover of incrementer */
-               gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK /
-                               CONFIG_SYS_HZ)) - gd->arch.lastinc) + now;
-       }
-       gd->arch.lastinc = now;
-       return gd->arch.tbl;
+       return tick_to_time(get_ticks());
 }
 
 /*
@@ -90,7 +131,14 @@ ulong get_timer_masked(void)
  */
 unsigned long long get_ticks(void)
 {
-       return get_timer(0);
+       ulong now = readl(&timer_base->tcrr);
+       ulong inc = now - gd->arch.lastinc;
+
+       if (gd->arch.tbl + inc < gd->arch.tbl)
+               gd->arch.tbu++;
+       gd->arch.tbl += inc;
+       gd->arch.lastinc = now;
+       return ((unsigned long long)gd->arch.tbu << 32) | gd->arch.tbl;
 }
 
 /*
@@ -99,5 +147,5 @@ unsigned long long get_ticks(void)
  */
 ulong get_tbclk(void)
 {
-       return CONFIG_SYS_HZ;
+       return gd->arch.timer_rate_hz;
 }
diff --git a/arch/arm/dts/imx6qdl.dtsi b/arch/arm/dts/imx6qdl.dtsi
new file mode 100644 (file)
index 0000000..06ec460
--- /dev/null
@@ -0,0 +1,800 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       aliases {
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+               gpio4 = &gpio5;
+               gpio5 = &gpio6;
+               gpio6 = &gpio7;
+       };
+
+       intc: interrupt-controller@00a01000 {
+               compatible = "arm,cortex-a9-gic";
+               #interrupt-cells = <3>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               interrupt-controller;
+               reg = <0x00a01000 0x1000>,
+                     <0x00a00100 0x100>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ckil {
+                       compatible = "fsl,imx-ckil", "fixed-clock";
+                       clock-frequency = <32768>;
+               };
+
+               ckih1 {
+                       compatible = "fsl,imx-ckih1", "fixed-clock";
+                       clock-frequency = <0>;
+               };
+
+               osc {
+                       compatible = "fsl,imx-osc", "fixed-clock";
+                       clock-frequency = <24000000>;
+               };
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&intc>;
+               ranges;
+
+               dma-apbh@00110000 {
+                       compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
+                       reg = <0x00110000 0x2000>;
+                       clocks = <&clks 106>;
+               };
+
+               gpmi: gpmi-nand@00112000 {
+                       compatible = "fsl,imx6q-gpmi-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
+                       reg-names = "gpmi-nand", "bch";
+                       interrupts = <0 13 0x04>, <0 15 0x04>;
+                       interrupt-names = "gpmi-dma", "bch";
+                       clocks = <&clks 152>, <&clks 153>, <&clks 151>,
+                                <&clks 150>, <&clks 149>;
+                       clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch",
+                                     "gpmi_bch_apb", "per1_bch";
+                       fsl,gpmi-dma-channel = <0>;
+                       status = "disabled";
+               };
+
+               timer@00a00600 {
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0x00a00600 0x20>;
+                       interrupts = <1 13 0xf01>;
+               };
+
+               L2: l2-cache@00a02000 {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x00a02000 0x1000>;
+                       interrupts = <0 92 0x04>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               aips-bus@02000000 { /* AIPS1 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x02000000 0x100000>;
+                       ranges;
+
+                       spba-bus@02000000 {
+                               compatible = "fsl,spba-bus", "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x02000000 0x40000>;
+                               ranges;
+
+                               spdif: spdif@02004000 {
+                                       reg = <0x02004000 0x4000>;
+                                       interrupts = <0 52 0x04>;
+                               };
+
+                               ecspi1: ecspi@02008000 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x02008000 0x4000>;
+                                       interrupts = <0 31 0x04>;
+                                       clocks = <&clks 112>, <&clks 112>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ecspi2: ecspi@0200c000 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x0200c000 0x4000>;
+                                       interrupts = <0 32 0x04>;
+                                       clocks = <&clks 113>, <&clks 113>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ecspi3: ecspi@02010000 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x02010000 0x4000>;
+                                       interrupts = <0 33 0x04>;
+                                       clocks = <&clks 114>, <&clks 114>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               ecspi4: ecspi@02014000 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x02014000 0x4000>;
+                                       interrupts = <0 34 0x04>;
+                                       clocks = <&clks 115>, <&clks 115>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               uart1: serial@02020000 {
+                                       compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+                                       reg = <0x02020000 0x4000>;
+                                       interrupts = <0 26 0x04>;
+                                       clocks = <&clks 160>, <&clks 161>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+
+                               esai: esai@02024000 {
+                                       reg = <0x02024000 0x4000>;
+                                       interrupts = <0 51 0x04>;
+                               };
+
+                               ssi1: ssi@02028000 {
+                                       compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+                                       reg = <0x02028000 0x4000>;
+                                       interrupts = <0 46 0x04>;
+                                       clocks = <&clks 178>;
+                                       fsl,fifo-depth = <15>;
+                                       fsl,ssi-dma-events = <38 37>;
+                                       status = "disabled";
+                               };
+
+                               ssi2: ssi@0202c000 {
+                                       compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+                                       reg = <0x0202c000 0x4000>;
+                                       interrupts = <0 47 0x04>;
+                                       clocks = <&clks 179>;
+                                       fsl,fifo-depth = <15>;
+                                       fsl,ssi-dma-events = <42 41>;
+                                       status = "disabled";
+                               };
+
+                               ssi3: ssi@02030000 {
+                                       compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+                                       reg = <0x02030000 0x4000>;
+                                       interrupts = <0 48 0x04>;
+                                       clocks = <&clks 180>;
+                                       fsl,fifo-depth = <15>;
+                                       fsl,ssi-dma-events = <46 45>;
+                                       status = "disabled";
+                               };
+
+                               asrc: asrc@02034000 {
+                                       reg = <0x02034000 0x4000>;
+                                       interrupts = <0 50 0x04>;
+                               };
+
+                               spba@0203c000 {
+                                       reg = <0x0203c000 0x4000>;
+                               };
+                       };
+
+                       vpu: vpu@02040000 {
+                               reg = <0x02040000 0x3c000>;
+                               interrupts = <0 3 0x04 0 12 0x04>;
+                       };
+
+                       aipstz@0207c000 { /* AIPSTZ1 */
+                               reg = <0x0207c000 0x4000>;
+                       };
+
+                       pwm1: pwm@02080000 {
+                               #pwm-cells = <2>;
+                               compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+                               reg = <0x02080000 0x4000>;
+                               interrupts = <0 83 0x04>;
+                               clocks = <&clks 62>, <&clks 145>;
+                               clock-names = "ipg", "per";
+                       };
+
+                       pwm2: pwm@02084000 {
+                               #pwm-cells = <2>;
+                               compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+                               reg = <0x02084000 0x4000>;
+                               interrupts = <0 84 0x04>;
+                               clocks = <&clks 62>, <&clks 146>;
+                               clock-names = "ipg", "per";
+                       };
+
+                       pwm3: pwm@02088000 {
+                               #pwm-cells = <2>;
+                               compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+                               reg = <0x02088000 0x4000>;
+                               interrupts = <0 85 0x04>;
+                               clocks = <&clks 62>, <&clks 147>;
+                               clock-names = "ipg", "per";
+                       };
+
+                       pwm4: pwm@0208c000 {
+                               #pwm-cells = <2>;
+                               compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+                               reg = <0x0208c000 0x4000>;
+                               interrupts = <0 86 0x04>;
+                               clocks = <&clks 62>, <&clks 148>;
+                               clock-names = "ipg", "per";
+                       };
+
+                       can1: flexcan@02090000 {
+                               reg = <0x02090000 0x4000>;
+                               interrupts = <0 110 0x04>;
+                       };
+
+                       can2: flexcan@02094000 {
+                               reg = <0x02094000 0x4000>;
+                               interrupts = <0 111 0x04>;
+                       };
+
+                       gpt: gpt@02098000 {
+                               compatible = "fsl,imx6q-gpt";
+                               reg = <0x02098000 0x4000>;
+                               interrupts = <0 55 0x04>;
+                       };
+
+                       gpio1: gpio@0209c000 {
+                               compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+                               reg = <0x0209c000 0x4000>;
+                               interrupts = <0 66 0x04 0 67 0x04>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio@020a0000 {
+                               compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+                               reg = <0x020a0000 0x4000>;
+                               interrupts = <0 68 0x04 0 69 0x04>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio3: gpio@020a4000 {
+                               compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+                               reg = <0x020a4000 0x4000>;
+                               interrupts = <0 70 0x04 0 71 0x04>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio4: gpio@020a8000 {
+                               compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+                               reg = <0x020a8000 0x4000>;
+                               interrupts = <0 72 0x04 0 73 0x04>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio5: gpio@020ac000 {
+                               compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+                               reg = <0x020ac000 0x4000>;
+                               interrupts = <0 74 0x04 0 75 0x04>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio6: gpio@020b0000 {
+                               compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+                               reg = <0x020b0000 0x4000>;
+                               interrupts = <0 76 0x04 0 77 0x04>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio7: gpio@020b4000 {
+                               compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+                               reg = <0x020b4000 0x4000>;
+                               interrupts = <0 78 0x04 0 79 0x04>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       kpp: kpp@020b8000 {
+                               reg = <0x020b8000 0x4000>;
+                               interrupts = <0 82 0x04>;
+                       };
+
+                       wdog1: wdog@020bc000 {
+                               compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+                               reg = <0x020bc000 0x4000>;
+                               interrupts = <0 80 0x04>;
+                               clocks = <&clks 0>;
+                       };
+
+                       wdog2: wdog@020c0000 {
+                               compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+                               reg = <0x020c0000 0x4000>;
+                               interrupts = <0 81 0x04>;
+                               clocks = <&clks 0>;
+                               status = "disabled";
+                       };
+
+                       clks: ccm@020c4000 {
+                               compatible = "fsl,imx6q-ccm";
+                               reg = <0x020c4000 0x4000>;
+                               interrupts = <0 87 0x04 0 88 0x04>;
+                               #clock-cells = <1>;
+                       };
+
+                       anatop: anatop@020c8000 {
+                               compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
+                               reg = <0x020c8000 0x1000>;
+                               interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
+
+                               regulator-1p1@110 {
+                                       compatible = "fsl,anatop-regulator";
+                                       regulator-name = "vdd1p1";
+                                       regulator-min-microvolt = <800000>;
+                                       regulator-max-microvolt = <1375000>;
+                                       regulator-always-on;
+                                       anatop-reg-offset = <0x110>;
+                                       anatop-vol-bit-shift = <8>;
+                                       anatop-vol-bit-width = <5>;
+                                       anatop-min-bit-val = <4>;
+                                       anatop-min-voltage = <800000>;
+                                       anatop-max-voltage = <1375000>;
+                               };
+
+                               regulator-3p0@120 {
+                                       compatible = "fsl,anatop-regulator";
+                                       regulator-name = "vdd3p0";
+                                       regulator-min-microvolt = <2800000>;
+                                       regulator-max-microvolt = <3150000>;
+                                       regulator-always-on;
+                                       anatop-reg-offset = <0x120>;
+                                       anatop-vol-bit-shift = <8>;
+                                       anatop-vol-bit-width = <5>;
+                                       anatop-min-bit-val = <0>;
+                                       anatop-min-voltage = <2625000>;
+                                       anatop-max-voltage = <3400000>;
+                               };
+
+                               regulator-2p5@130 {
+                                       compatible = "fsl,anatop-regulator";
+                                       regulator-name = "vdd2p5";
+                                       regulator-min-microvolt = <2000000>;
+                                       regulator-max-microvolt = <2750000>;
+                                       regulator-always-on;
+                                       anatop-reg-offset = <0x130>;
+                                       anatop-vol-bit-shift = <8>;
+                                       anatop-vol-bit-width = <5>;
+                                       anatop-min-bit-val = <0>;
+                                       anatop-min-voltage = <2000000>;
+                                       anatop-max-voltage = <2750000>;
+                               };
+
+                               reg_arm: regulator-vddcore@140 {
+                                       compatible = "fsl,anatop-regulator";
+                                       regulator-name = "cpu";
+                                       regulator-min-microvolt = <725000>;
+                                       regulator-max-microvolt = <1450000>;
+                                       regulator-always-on;
+                                       anatop-reg-offset = <0x140>;
+                                       anatop-vol-bit-shift = <0>;
+                                       anatop-vol-bit-width = <5>;
+                                       anatop-delay-reg-offset = <0x170>;
+                                       anatop-delay-bit-shift = <24>;
+                                       anatop-delay-bit-width = <2>;
+                                       anatop-min-bit-val = <1>;
+                                       anatop-min-voltage = <725000>;
+                                       anatop-max-voltage = <1450000>;
+                               };
+
+                               reg_pu: regulator-vddpu@140 {
+                                       compatible = "fsl,anatop-regulator";
+                                       regulator-name = "vddpu";
+                                       regulator-min-microvolt = <725000>;
+                                       regulator-max-microvolt = <1450000>;
+                                       regulator-always-on;
+                                       anatop-reg-offset = <0x140>;
+                                       anatop-vol-bit-shift = <9>;
+                                       anatop-vol-bit-width = <5>;
+                                       anatop-delay-reg-offset = <0x170>;
+                                       anatop-delay-bit-shift = <26>;
+                                       anatop-delay-bit-width = <2>;
+                                       anatop-min-bit-val = <1>;
+                                       anatop-min-voltage = <725000>;
+                                       anatop-max-voltage = <1450000>;
+                               };
+
+                               reg_soc: regulator-vddsoc@140 {
+                                       compatible = "fsl,anatop-regulator";
+                                       regulator-name = "vddsoc";
+                                       regulator-min-microvolt = <725000>;
+                                       regulator-max-microvolt = <1450000>;
+                                       regulator-always-on;
+                                       anatop-reg-offset = <0x140>;
+                                       anatop-vol-bit-shift = <18>;
+                                       anatop-vol-bit-width = <5>;
+                                       anatop-delay-reg-offset = <0x170>;
+                                       anatop-delay-bit-shift = <28>;
+                                       anatop-delay-bit-width = <2>;
+                                       anatop-min-bit-val = <1>;
+                                       anatop-min-voltage = <725000>;
+                                       anatop-max-voltage = <1450000>;
+                               };
+                       };
+
+                       usbphy1: usbphy@020c9000 {
+                               compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
+                               reg = <0x020c9000 0x1000>;
+                               interrupts = <0 44 0x04>;
+                               clocks = <&clks 182>;
+                       };
+
+                       usbphy2: usbphy@020ca000 {
+                               compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
+                               reg = <0x020ca000 0x1000>;
+                               interrupts = <0 45 0x04>;
+                               clocks = <&clks 183>;
+                       };
+
+                       snvs@020cc000 {
+                               compatible = "fsl,sec-v4.0-mon", "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x020cc000 0x4000>;
+
+                               snvs-rtc-lp@34 {
+                                       compatible = "fsl,sec-v4.0-mon-rtc-lp";
+                                       reg = <0x34 0x58>;
+                                       interrupts = <0 19 0x04 0 20 0x04>;
+                               };
+                       };
+
+                       epit1: epit@020d0000 { /* EPIT1 */
+                               reg = <0x020d0000 0x4000>;
+                               interrupts = <0 56 0x04>;
+                       };
+
+                       epit2: epit@020d4000 { /* EPIT2 */
+                               reg = <0x020d4000 0x4000>;
+                               interrupts = <0 57 0x04>;
+                       };
+
+                       src: src@020d8000 {
+                               compatible = "fsl,imx6q-src";
+                               reg = <0x020d8000 0x4000>;
+                               interrupts = <0 91 0x04 0 96 0x04>;
+                       };
+
+                       gpc: gpc@020dc000 {
+                               compatible = "fsl,imx6q-gpc";
+                               reg = <0x020dc000 0x4000>;
+                               interrupts = <0 89 0x04 0 90 0x04>;
+                       };
+
+                       gpr: iomuxc-gpr@020e0000 {
+                               compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
+                               reg = <0x020e0000 0x38>;
+                       };
+
+                       dcic1: dcic@020e4000 {
+                               reg = <0x020e4000 0x4000>;
+                               interrupts = <0 124 0x04>;
+                       };
+
+                       dcic2: dcic@020e8000 {
+                               reg = <0x020e8000 0x4000>;
+                               interrupts = <0 125 0x04>;
+                       };
+
+                       sdma: sdma@020ec000 {
+                               compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
+                               reg = <0x020ec000 0x4000>;
+                               interrupts = <0 2 0x04>;
+                               clocks = <&clks 155>, <&clks 155>;
+                               clock-names = "ipg", "ahb";
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
+                       };
+               };
+
+               aips-bus@02100000 { /* AIPS2 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x02100000 0x100000>;
+                       ranges;
+
+                       caam@02100000 {
+                               reg = <0x02100000 0x40000>;
+                               interrupts = <0 105 0x04 0 106 0x04>;
+                       };
+
+                       aipstz@0217c000 { /* AIPSTZ2 */
+                               reg = <0x0217c000 0x4000>;
+                       };
+
+                       usbotg: usb@02184000 {
+                               compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+                               reg = <0x02184000 0x200>;
+                               interrupts = <0 43 0x04>;
+                               clocks = <&clks 162>;
+                               fsl,usbphy = <&usbphy1>;
+                               fsl,usbmisc = <&usbmisc 0>;
+                               status = "disabled";
+                       };
+
+                       usbh1: usb@02184200 {
+                               compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+                               reg = <0x02184200 0x200>;
+                               interrupts = <0 40 0x04>;
+                               clocks = <&clks 162>;
+                               fsl,usbphy = <&usbphy2>;
+                               fsl,usbmisc = <&usbmisc 1>;
+                               status = "disabled";
+                       };
+
+                       usbh2: usb@02184400 {
+                               compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+                               reg = <0x02184400 0x200>;
+                               interrupts = <0 41 0x04>;
+                               clocks = <&clks 162>;
+                               fsl,usbmisc = <&usbmisc 2>;
+                               status = "disabled";
+                       };
+
+                       usbh3: usb@02184600 {
+                               compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+                               reg = <0x02184600 0x200>;
+                               interrupts = <0 42 0x04>;
+                               clocks = <&clks 162>;
+                               fsl,usbmisc = <&usbmisc 3>;
+                               status = "disabled";
+                       };
+
+                       usbmisc: usbmisc: usbmisc@02184800 {
+                               #index-cells = <1>;
+                               compatible = "fsl,imx6q-usbmisc";
+                               reg = <0x02184800 0x200>;
+                               clocks = <&clks 162>;
+                       };
+
+                       fec: ethernet@02188000 {
+                               compatible = "fsl,imx6q-fec";
+                               reg = <0x02188000 0x4000>;
+                               interrupts = <0 118 0x04 0 119 0x04>;
+                               clocks = <&clks 117>, <&clks 117>, <&clks 190>;
+                               clock-names = "ipg", "ahb", "ptp";
+                               status = "disabled";
+                       };
+
+                       mlb@0218c000 {
+                               reg = <0x0218c000 0x4000>;
+                               interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
+                       };
+
+                       usdhc1: usdhc@02190000 {
+                               compatible = "fsl,imx6q-usdhc";
+                               reg = <0x02190000 0x4000>;
+                               interrupts = <0 22 0x04>;
+                               clocks = <&clks 163>, <&clks 163>, <&clks 163>;
+                               clock-names = "ipg", "ahb", "per";
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       usdhc2: usdhc@02194000 {
+                               compatible = "fsl,imx6q-usdhc";
+                               reg = <0x02194000 0x4000>;
+                               interrupts = <0 23 0x04>;
+                               clocks = <&clks 164>, <&clks 164>, <&clks 164>;
+                               clock-names = "ipg", "ahb", "per";
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       usdhc3: usdhc@02198000 {
+                               compatible = "fsl,imx6q-usdhc";
+                               reg = <0x02198000 0x4000>;
+                               interrupts = <0 24 0x04>;
+                               clocks = <&clks 165>, <&clks 165>, <&clks 165>;
+                               clock-names = "ipg", "ahb", "per";
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       usdhc4: usdhc@0219c000 {
+                               compatible = "fsl,imx6q-usdhc";
+                               reg = <0x0219c000 0x4000>;
+                               interrupts = <0 25 0x04>;
+                               clocks = <&clks 166>, <&clks 166>, <&clks 166>;
+                               clock-names = "ipg", "ahb", "per";
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@021a0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+                               reg = <0x021a0000 0x4000>;
+                               interrupts = <0 36 0x04>;
+                               clocks = <&clks 125>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@021a4000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+                               reg = <0x021a4000 0x4000>;
+                               interrupts = <0 37 0x04>;
+                               clocks = <&clks 126>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@021a8000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+                               reg = <0x021a8000 0x4000>;
+                               interrupts = <0 38 0x04>;
+                               clocks = <&clks 127>;
+                               status = "disabled";
+                       };
+
+                       romcp@021ac000 {
+                               reg = <0x021ac000 0x4000>;
+                       };
+
+                       mmdc0: mmdc@021b0000 { /* MMDC0 */
+                               compatible = "fsl,imx6q-mmdc";
+                               reg = <0x021b0000 0x4000>;
+                       };
+
+                       mmdc1: mmdc@021b4000 { /* MMDC1 */
+                               reg = <0x021b4000 0x4000>;
+                       };
+
+                       weim@021b8000 {
+                               reg = <0x021b8000 0x4000>;
+                               interrupts = <0 14 0x04>;
+                       };
+
+                       ocotp@021bc000 {
+                               compatible = "fsl,imx6q-ocotp";
+                               reg = <0x021bc000 0x4000>;
+                       };
+
+                       ocotp@021c0000 {
+                               reg = <0x021c0000 0x4000>;
+                               interrupts = <0 21 0x04>;
+                       };
+
+                       tzasc@021d0000 { /* TZASC1 */
+                               reg = <0x021d0000 0x4000>;
+                               interrupts = <0 108 0x04>;
+                       };
+
+                       tzasc@021d4000 { /* TZASC2 */
+                               reg = <0x021d4000 0x4000>;
+                               interrupts = <0 109 0x04>;
+                       };
+
+                       audmux: audmux@021d8000 {
+                               compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
+                               reg = <0x021d8000 0x4000>;
+                               status = "disabled";
+                       };
+
+                       mipi@021dc000 { /* MIPI-CSI */
+                               reg = <0x021dc000 0x4000>;
+                       };
+
+                       mipi@021e0000 { /* MIPI-DSI */
+                               reg = <0x021e0000 0x4000>;
+                       };
+
+                       vdoa@021e4000 {
+                               reg = <0x021e4000 0x4000>;
+                               interrupts = <0 18 0x04>;
+                       };
+
+                       uart2: serial@021e8000 {
+                               compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+                               reg = <0x021e8000 0x4000>;
+                               interrupts = <0 27 0x04>;
+                               clocks = <&clks 160>, <&clks 161>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       uart3: serial@021ec000 {
+                               compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+                               reg = <0x021ec000 0x4000>;
+                               interrupts = <0 28 0x04>;
+                               clocks = <&clks 160>, <&clks 161>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       uart4: serial@021f0000 {
+                               compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+                               reg = <0x021f0000 0x4000>;
+                               interrupts = <0 29 0x04>;
+                               clocks = <&clks 160>, <&clks 161>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       uart5: serial@021f4000 {
+                               compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+                               reg = <0x021f4000 0x4000>;
+                               interrupts = <0 30 0x04>;
+                               clocks = <&clks 160>, <&clks 161>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+               };
+
+               ipu1: ipu@02400000 {
+                       #crtc-cells = <1>;
+                       compatible = "fsl,imx6q-ipu";
+                       reg = <0x02400000 0x400000>;
+                       interrupts = <0 6 0x4 0 5 0x4>;
+                       clocks = <&clks 130>, <&clks 131>, <&clks 132>;
+                       clock-names = "bus", "di0", "di1";
+               };
+       };
+};
diff --git a/arch/arm/dts/mx28.dtsi b/arch/arm/dts/mx28.dtsi
new file mode 100644 (file)
index 0000000..a9bda8e
--- /dev/null
@@ -0,0 +1,872 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       interrupt-parent = <&icoll>;
+
+       aliases {
+               gpio0 = &gpio0;
+               gpio1 = &gpio1;
+               gpio2 = &gpio2;
+               gpio3 = &gpio3;
+               gpio4 = &gpio4;
+               saif0 = &saif0;
+               saif1 = &saif1;
+               serial0 = &auart0;
+               serial1 = &auart1;
+               serial2 = &auart2;
+               serial3 = &auart3;
+               serial4 = &auart4;
+       };
+
+       cpus {
+               cpu@0 {
+                       compatible = "arm,arm926ejs";
+               };
+       };
+
+       apb@80000000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x80000000 0x80000>;
+               ranges;
+
+               apbh@80000000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x80000000 0x3c900>;
+                       ranges;
+
+                       icoll: interrupt-controller@80000000 {
+                               compatible = "fsl,imx28-icoll", "fsl,mxs-icoll";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x80000000 0x2000>;
+                       };
+
+                       hsadc@80002000 {
+                               reg = <0x80002000 0x2000>;
+                               interrupts = <13 87>;
+                               status = "disabled";
+                       };
+
+                       dma-apbh@80004000 {
+                               compatible = "fsl,imx28-dma-apbh";
+                               reg = <0x80004000 0x2000>;
+                       };
+
+                       perfmon@80006000 {
+                               reg = <0x80006000 0x800>;
+                               interrupts = <27>;
+                               status = "disabled";
+                       };
+
+                       gpmi-nand@8000c000 {
+                               compatible = "fsl,imx28-gpmi-nand";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>;
+                               reg-names = "gpmi-nand", "bch";
+                               interrupts = <88>, <41>;
+                               interrupt-names = "gpmi-dma", "bch";
+                               fsl,gpmi-dma-channel = <4>;
+                               status = "disabled";
+                       };
+
+                       ssp0: ssp@80010000 {
+                               reg = <0x80010000 0x2000>;
+                               interrupts = <96 82>;
+                               fsl,ssp-dma-channel = <0>;
+                               status = "disabled";
+                       };
+
+                       ssp1: ssp@80012000 {
+                               reg = <0x80012000 0x2000>;
+                               interrupts = <97 83>;
+                               fsl,ssp-dma-channel = <1>;
+                               status = "disabled";
+                       };
+
+                       ssp2: ssp@80014000 {
+                               reg = <0x80014000 0x2000>;
+                               interrupts = <98 84>;
+                               fsl,ssp-dma-channel = <2>;
+                               status = "disabled";
+                       };
+
+                       ssp3: ssp@80016000 {
+                               reg = <0x80016000 0x2000>;
+                               interrupts = <99 85>;
+                               fsl,ssp-dma-channel = <3>;
+                               status = "disabled";
+                       };
+
+                       pinctrl@80018000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx28-pinctrl", "simple-bus";
+                               reg = <0x80018000 0x2000>;
+
+                               gpio0: gpio@0 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <127>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio1: gpio@1 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <126>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio2: gpio@2 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <125>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio3: gpio@3 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <124>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio4: gpio@4 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <123>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               duart_pins_a: duart@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3102 /* MX28_PAD_PWM0__DUART_RX */
+                                               0x3112 /* MX28_PAD_PWM1__DUART_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               duart_pins_b: duart@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               0x3022 /* MX28_PAD_AUART0_CTS__DUART_RX */
+                                               0x3032 /* MX28_PAD_AUART0_RTS__DUART_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               duart_4pins_a: duart-4pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3022 /* MX28_PAD_AUART0_CTS__DUART_RX */
+                                               0x3032 /* MX28_PAD_AUART0_RTS__DUART_TX */
+                                               0x3002 /* MX28_PAD_AUART0_RX__DUART_CTS */
+                                               0x3012 /* MX28_PAD_AUART0_TX__DUART_RTS */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               gpmi_pins_a: gpmi-nand@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x0000 /* MX28_PAD_GPMI_D00__GPMI_D0 */
+                                               0x0010 /* MX28_PAD_GPMI_D01__GPMI_D1 */
+                                               0x0020 /* MX28_PAD_GPMI_D02__GPMI_D2 */
+                                               0x0030 /* MX28_PAD_GPMI_D03__GPMI_D3 */
+                                               0x0040 /* MX28_PAD_GPMI_D04__GPMI_D4 */
+                                               0x0050 /* MX28_PAD_GPMI_D05__GPMI_D5 */
+                                               0x0060 /* MX28_PAD_GPMI_D06__GPMI_D6 */
+                                               0x0070 /* MX28_PAD_GPMI_D07__GPMI_D7 */
+                                               0x0100 /* MX28_PAD_GPMI_CE0N__GPMI_CE0N */
+                                               0x0140 /* MX28_PAD_GPMI_RDY0__GPMI_READY0 */
+                                               0x0180 /* MX28_PAD_GPMI_RDN__GPMI_RDN */
+                                               0x0190 /* MX28_PAD_GPMI_WRN__GPMI_WRN */
+                                               0x01a0 /* MX28_PAD_GPMI_ALE__GPMI_ALE */
+                                               0x01b0 /* MX28_PAD_GPMI_CLE__GPMI_CLE */
+                                               0x01c0 /* MX28_PAD_GPMI_RESETN__GPMI_RESETN */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               gpmi_status_cfg: gpmi-status-cfg {
+                                       fsl,pinmux-ids = <
+                                               0x0180 /* MX28_PAD_GPMI_RDN__GPMI_RDN */
+                                               0x0190 /* MX28_PAD_GPMI_WRN__GPMI_WRN */
+                                               0x01c0 /* MX28_PAD_GPMI_RESETN__GPMI_RESETN */
+                                       >;
+                                       fsl,drive-strength = <2>;
+                               };
+
+                               auart0_pins_a: auart0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3000 /* MX28_PAD_AUART0_RX__AUART0_RX */
+                                               0x3010 /* MX28_PAD_AUART0_TX__AUART0_TX */
+                                               0x3020 /* MX28_PAD_AUART0_CTS__AUART0_CTS */
+                                               0x3030 /* MX28_PAD_AUART0_RTS__AUART0_RTS */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart0_2pins_a: auart0-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3000 /* MX28_PAD_AUART0_RX__AUART0_RX */
+                                               0x3010 /* MX28_PAD_AUART0_TX__AUART0_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart1_pins_a: auart1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3040 /* MX28_PAD_AUART1_RX__AUART1_RX */
+                                               0x3050 /* MX28_PAD_AUART1_TX__AUART1_TX */
+                                               0x3060 /* MX28_PAD_AUART1_CTS__AUART1_CTS */
+                                               0x3070 /* MX28_PAD_AUART1_RTS__AUART1_RTS */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart1_2pins_a: auart1-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3040 /* MX28_PAD_AUART1_RX__AUART1_RX */
+                                               0x3050 /* MX28_PAD_AUART1_TX__AUART1_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart2_2pins_a: auart2-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2101 /* MX28_PAD_SSP2_SCK__AUART2_RX */
+                                               0x2111 /* MX28_PAD_SSP2_MOSI__AUART2_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart3_pins_a: auart3@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x30c0 /* MX28_PAD_AUART3_RX__AUART3_RX */
+                                               0x30d0 /* MX28_PAD_AUART3_TX__AUART3_TX */
+                                               0x30e0 /* MX28_PAD_AUART3_CTS__AUART3_CTS */
+                                               0x30f0 /* MX28_PAD_AUART3_RTS__AUART3_RTS */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart3_2pins_a: auart3-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2121 /* MX28_PAD_SSP2_MISO__AUART3_RX */
+                                               0x2131 /* MX28_PAD_SSP2_SS0__AUART3_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               mac0_pins_a: mac0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x4000 /* MX28_PAD_ENET0_MDC__ENET0_MDC */
+                                               0x4010 /* MX28_PAD_ENET0_MDIO__ENET0_MDIO */
+                                               0x4020 /* MX28_PAD_ENET0_RX_EN__ENET0_RX_EN */
+                                               0x4030 /* MX28_PAD_ENET0_RXD0__ENET0_RXD0 */
+                                               0x4040 /* MX28_PAD_ENET0_RXD1__ENET0_RXD1 */
+                                               0x4060 /* MX28_PAD_ENET0_TX_EN__ENET0_TX_EN */
+                                               0x4070 /* MX28_PAD_ENET0_TXD0__ENET0_TXD0 */
+                                               0x4080 /* MX28_PAD_ENET0_TXD1__ENET0_TXD1 */
+                                               0x4100 /* MX28_PAD_ENET_CLK__CLKCTRL_ENET */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               mac1_pins_a: mac1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x40f1 /* MX28_PAD_ENET0_CRS__ENET1_RX_EN */
+                                               0x4091 /* MX28_PAD_ENET0_RXD2__ENET1_RXD0 */
+                                               0x40a1 /* MX28_PAD_ENET0_RXD3__ENET1_RXD1 */
+                                               0x40e1 /* MX28_PAD_ENET0_COL__ENET1_TX_EN */
+                                               0x40b1 /* MX28_PAD_ENET0_TXD2__ENET1_TXD0 */
+                                               0x40c1 /* MX28_PAD_ENET0_TXD3__ENET1_TXD1 */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               mmc0_8bit_pins_a: mmc0-8bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2000 /* MX28_PAD_SSP0_DATA0__SSP0_D0 */
+                                               0x2010 /* MX28_PAD_SSP0_DATA1__SSP0_D1 */
+                                               0x2020 /* MX28_PAD_SSP0_DATA2__SSP0_D2 */
+                                               0x2030 /* MX28_PAD_SSP0_DATA3__SSP0_D3 */
+                                               0x2040 /* MX28_PAD_SSP0_DATA4__SSP0_D4 */
+                                               0x2050 /* MX28_PAD_SSP0_DATA5__SSP0_D5 */
+                                               0x2060 /* MX28_PAD_SSP0_DATA6__SSP0_D6 */
+                                               0x2070 /* MX28_PAD_SSP0_DATA7__SSP0_D7 */
+                                               0x2080 /* MX28_PAD_SSP0_CMD__SSP0_CMD */
+                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
+                                               0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               mmc0_4bit_pins_a: mmc0-4bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2000 /* MX28_PAD_SSP0_DATA0__SSP0_D0 */
+                                               0x2010 /* MX28_PAD_SSP0_DATA1__SSP0_D1 */
+                                               0x2020 /* MX28_PAD_SSP0_DATA2__SSP0_D2 */
+                                               0x2030 /* MX28_PAD_SSP0_DATA3__SSP0_D3 */
+                                               0x2080 /* MX28_PAD_SSP0_CMD__SSP0_CMD */
+                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
+                                               0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               mmc0_cd_cfg: mmc0-cd-cfg {
+                                       fsl,pinmux-ids = <
+                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
+                                       >;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               mmc0_sck_cfg: mmc0-sck-cfg {
+                                       fsl,pinmux-ids = <
+                                               0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */
+                                       >;
+                                       fsl,drive-strength = <2>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               i2c0_pins_a: i2c0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3180 /* MX28_PAD_I2C0_SCL__I2C0_SCL */
+                                               0x3190 /* MX28_PAD_I2C0_SDA__I2C0_SDA */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               i2c0_pins_b: i2c0@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               0x3001 /* MX28_PAD_AUART0_RX__I2C0_SCL */
+                                               0x3011 /* MX28_PAD_AUART0_TX__I2C0_SDA */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               i2c1_pins_a: i2c1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3101 /* MX28_PAD_PWM0__I2C1_SCL */
+                                               0x3111 /* MX28_PAD_PWM1__I2C1_SDA */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               saif0_pins_a: saif0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3140 /* MX28_PAD_SAIF0_MCLK__SAIF0_MCLK */
+                                               0x3150 /* MX28_PAD_SAIF0_LRCLK__SAIF0_LRCLK */
+                                               0x3160 /* MX28_PAD_SAIF0_BITCLK__SAIF0_BITCLK */
+                                               0x3170 /* MX28_PAD_SAIF0_SDATA0__SAIF0_SDATA0 */
+                                       >;
+                                       fsl,drive-strength = <2>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               saif1_pins_a: saif1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x31a0 /* MX28_PAD_SAIF1_SDATA0__SAIF1_SDATA0 */
+                                       >;
+                                       fsl,drive-strength = <2>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               pwm0_pins_a: pwm0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3100 /* MX28_PAD_PWM0__PWM_0 */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               pwm2_pins_a: pwm2@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3120 /* MX28_PAD_PWM2__PWM_2 */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               pwm4_pins_a: pwm4@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x31d0 /* MX28_PAD_PWM4__PWM_4 */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               lcdif_24bit_pins_a: lcdif-24bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x1000 /* MX28_PAD_LCD_D00__LCD_D0 */
+                                               0x1010 /* MX28_PAD_LCD_D01__LCD_D1 */
+                                               0x1020 /* MX28_PAD_LCD_D02__LCD_D2 */
+                                               0x1030 /* MX28_PAD_LCD_D03__LCD_D3 */
+                                               0x1040 /* MX28_PAD_LCD_D04__LCD_D4 */
+                                               0x1050 /* MX28_PAD_LCD_D05__LCD_D5 */
+                                               0x1060 /* MX28_PAD_LCD_D06__LCD_D6 */
+                                               0x1070 /* MX28_PAD_LCD_D07__LCD_D7 */
+                                               0x1080 /* MX28_PAD_LCD_D08__LCD_D8 */
+                                               0x1090 /* MX28_PAD_LCD_D09__LCD_D9 */
+                                               0x10a0 /* MX28_PAD_LCD_D10__LCD_D10 */
+                                               0x10b0 /* MX28_PAD_LCD_D11__LCD_D11 */
+                                               0x10c0 /* MX28_PAD_LCD_D12__LCD_D12 */
+                                               0x10d0 /* MX28_PAD_LCD_D13__LCD_D13 */
+                                               0x10e0 /* MX28_PAD_LCD_D14__LCD_D14 */
+                                               0x10f0 /* MX28_PAD_LCD_D15__LCD_D15 */
+                                               0x1100 /* MX28_PAD_LCD_D16__LCD_D16 */
+                                               0x1110 /* MX28_PAD_LCD_D17__LCD_D17 */
+                                               0x1120 /* MX28_PAD_LCD_D18__LCD_D18 */
+                                               0x1130 /* MX28_PAD_LCD_D19__LCD_D19 */
+                                               0x1140 /* MX28_PAD_LCD_D20__LCD_D20 */
+                                               0x1150 /* MX28_PAD_LCD_D21__LCD_D21 */
+                                               0x1160 /* MX28_PAD_LCD_D22__LCD_D22 */
+                                               0x1170 /* MX28_PAD_LCD_D23__LCD_D23 */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               can0_pins_a: can0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x0161 /* MX28_PAD_GPMI_RDY2__CAN0_TX */
+                                               0x0171 /* MX28_PAD_GPMI_RDY3__CAN0_RX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               can1_pins_a: can1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x0121 /* MX28_PAD_GPMI_CE2N__CAN1_TX */
+                                               0x0131 /* MX28_PAD_GPMI_CE3N__CAN1_RX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               spi2_pins_a: spi2@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2100 /* MX28_PAD_SSP2_SCK__SSP2_SCK */
+                                               0x2110 /* MX28_PAD_SSP2_MOSI__SSP2_CMD */
+                                               0x2120 /* MX28_PAD_SSP2_MISO__SSP2_D0 */
+                                               0x2130 /* MX28_PAD_SSP2_SS0__SSP2_D3 */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               usbphy0_pins_a: usbphy0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2152 /* MX28_PAD_SSP2_SS2__USB0_OVERCURRENT */
+                                       >;
+                                       fsl,drive-strength = <2>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               usbphy0_pins_b: usbphy0@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               0x3061 /* MX28_PAD_AUART1_CTS__USB0_OVERCURRENT */
+                                       >;
+                                       fsl,drive-strength = <2>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               usbphy1_pins_a: usbphy1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2142 /* MX28_PAD_SSP2_SS1__USB1_OVERCURRENT */
+                                       >;
+                                       fsl,drive-strength = <2>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+                       };
+
+                       digctl@8001c000 {
+                               reg = <0x8001c000 0x2000>;
+                               interrupts = <89>;
+                               status = "disabled";
+                       };
+
+                       etm@80022000 {
+                               reg = <0x80022000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       dma-apbx@80024000 {
+                               compatible = "fsl,imx28-dma-apbx";
+                               reg = <0x80024000 0x2000>;
+                       };
+
+                       dcp@80028000 {
+                               reg = <0x80028000 0x2000>;
+                               interrupts = <52 53 54>;
+                               status = "disabled";
+                       };
+
+                       pxp@8002a000 {
+                               reg = <0x8002a000 0x2000>;
+                               interrupts = <39>;
+                               status = "disabled";
+                       };
+
+                       ocotp@8002c000 {
+                               reg = <0x8002c000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       axi-ahb@8002e000 {
+                               reg = <0x8002e000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       lcdif@80030000 {
+                               compatible = "fsl,imx28-lcdif";
+                               reg = <0x80030000 0x2000>;
+                               interrupts = <38 86>;
+                               status = "disabled";
+                       };
+
+                       can0: can@80032000 {
+                               compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan";
+                               reg = <0x80032000 0x2000>;
+                               interrupts = <8>;
+                               status = "disabled";
+                       };
+
+                       can1: can@80034000 {
+                               compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan";
+                               reg = <0x80034000 0x2000>;
+                               interrupts = <9>;
+                               status = "disabled";
+                       };
+
+                       simdbg@8003c000 {
+                               reg = <0x8003c000 0x200>;
+                               status = "disabled";
+                       };
+
+                       simgpmisel@8003c200 {
+                               reg = <0x8003c200 0x100>;
+                               status = "disabled";
+                       };
+
+                       simsspsel@8003c300 {
+                               reg = <0x8003c300 0x100>;
+                               status = "disabled";
+                       };
+
+                       simmemsel@8003c400 {
+                               reg = <0x8003c400 0x100>;
+                               status = "disabled";
+                       };
+
+                       gpiomon@8003c500 {
+                               reg = <0x8003c500 0x100>;
+                               status = "disabled";
+                       };
+
+                       simenet@8003c700 {
+                               reg = <0x8003c700 0x100>;
+                               status = "disabled";
+                       };
+
+                       armjtag@8003c800 {
+                               reg = <0x8003c800 0x100>;
+                               status = "disabled";
+                       };
+                };
+
+               apbx@80040000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x80040000 0x40000>;
+                       ranges;
+
+                       clkctl@80040000 {
+                               reg = <0x80040000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       saif0: saif@80042000 {
+                               compatible = "fsl,imx28-saif";
+                               reg = <0x80042000 0x2000>;
+                               interrupts = <59 80>;
+                               fsl,saif-dma-channel = <4>;
+                               status = "disabled";
+                       };
+
+                       power@80044000 {
+                               reg = <0x80044000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       saif1: saif@80046000 {
+                               compatible = "fsl,imx28-saif";
+                               reg = <0x80046000 0x2000>;
+                               interrupts = <58 81>;
+                               fsl,saif-dma-channel = <5>;
+                               status = "disabled";
+                       };
+
+                       lradc@80050000 {
+                               compatible = "fsl,imx28-lradc";
+                               reg = <0x80050000 0x2000>;
+                               interrupts = <10 14 15 16 17 18 19
+                                               20 21 22 23 24 25>;
+                               status = "disabled";
+                       };
+
+                       spdif@80054000 {
+                               reg = <0x80054000 0x2000>;
+                               interrupts = <45 66>;
+                               status = "disabled";
+                       };
+
+                       rtc@80056000 {
+                               compatible = "fsl,imx28-rtc", "fsl,stmp3xxx-rtc";
+                               reg = <0x80056000 0x2000>;
+                               interrupts = <29>;
+                       };
+
+                       i2c0: i2c@80058000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx28-i2c";
+                               reg = <0x80058000 0x2000>;
+                               interrupts = <111 68>;
+                               clock-frequency = <100000>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@8005a000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx28-i2c";
+                               reg = <0x8005a000 0x2000>;
+                               interrupts = <110 69>;
+                               clock-frequency = <100000>;
+                               status = "disabled";
+                       };
+
+                       pwm: pwm@80064000 {
+                               compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
+                               reg = <0x80064000 0x2000>;
+                               #pwm-cells = <2>;
+                               fsl,pwm-number = <8>;
+                               status = "disabled";
+                       };
+
+                       timrot@80068000 {
+                               reg = <0x80068000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       auart0: serial@8006a000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x8006a000 0x2000>;
+                               interrupts = <112 70 71>;
+                               status = "disabled";
+                       };
+
+                       auart1: serial@8006c000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x8006c000 0x2000>;
+                               interrupts = <113 72 73>;
+                               status = "disabled";
+                       };
+
+                       auart2: serial@8006e000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x8006e000 0x2000>;
+                               interrupts = <114 74 75>;
+                               status = "disabled";
+                       };
+
+                       auart3: serial@80070000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x80070000 0x2000>;
+                               interrupts = <115 76 77>;
+                               status = "disabled";
+                       };
+
+                       auart4: serial@80072000 {
+                               compatible = "fsl,imx28-auart", "fsl,imx23-auart";
+                               reg = <0x80072000 0x2000>;
+                               interrupts = <116 78 79>;
+                               status = "disabled";
+                       };
+
+                       duart: serial@80074000 {
+                               compatible = "arm,pl011", "arm,primecell";
+                               reg = <0x80074000 0x1000>;
+                               interrupts = <47>;
+                               status = "disabled";
+                       };
+
+                       usbphy0: usbphy@8007c000 {
+                               compatible = "fsl,imx28-usbphy", "fsl,imx23-usbphy";
+                               reg = <0x8007c000 0x2000>;
+                               status = "disabled";
+                       };
+
+                       usbphy1: usbphy@8007e000 {
+                               compatible = "fsl,imx28-usbphy", "fsl,imx23-usbphy";
+                               reg = <0x8007e000 0x2000>;
+                               status = "disabled";
+                       };
+               };
+       };
+
+       ahb@80080000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x80080000 0x80000>;
+               ranges;
+
+               usb0: usb@80080000 {
+                       compatible = "fsl,imx28-usb", "fsl,imx27-usb";
+                       reg = <0x80080000 0x10000>;
+                       interrupts = <93>;
+                       fsl,usbphy = <&usbphy0>;
+                       status = "disabled";
+               };
+
+               usb1: usb@80090000 {
+                       compatible = "fsl,imx28-usb", "fsl,imx27-usb";
+                       reg = <0x80090000 0x10000>;
+                       interrupts = <92>;
+                       fsl,usbphy = <&usbphy1>;
+                       status = "disabled";
+               };
+
+               dflpt@800c0000 {
+                       reg = <0x800c0000 0x10000>;
+                       status = "disabled";
+               };
+
+               mac0: ethernet@800f0000 {
+                       compatible = "fsl,imx28-fec";
+                       reg = <0x800f0000 0x4000>;
+                       interrupts = <101>;
+                       status = "disabled";
+               };
+
+               mac1: ethernet@800f4000 {
+                       compatible = "fsl,imx28-fec";
+                       reg = <0x800f4000 0x4000>;
+                       interrupts = <102>;
+                       status = "disabled";
+               };
+
+               switch@800f8000 {
+                       reg = <0x800f8000 0x8000>;
+                       status = "disabled";
+               };
+
+       };
+};
diff --git a/arch/arm/dts/mx51.dtsi b/arch/arm/dts/mx51.dtsi
new file mode 100644 (file)
index 0000000..3688f31
--- /dev/null
@@ -0,0 +1,476 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+        aliases {
+                serial0 = &uart1;
+                serial1 = &uart2;
+                serial2 = &uart3;
+               ethernet0 = &fec0;
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+       };
+
+       tzic: tz-interrupt-controller@e0000000 {
+               compatible = "fsl,imx51-tzic", "fsl,tzic";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = <0xe0000000 0x4000>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ckil {
+                       compatible = "fsl,imx-ckil", "fixed-clock";
+                       clock-frequency = <32768>;
+               };
+
+               ckih1 {
+                       compatible = "fsl,imx-ckih1", "fixed-clock";
+                       clock-frequency = <22579200>;
+               };
+
+               ckih2 {
+                       compatible = "fsl,imx-ckih2", "fixed-clock";
+                       clock-frequency = <0>;
+               };
+
+               osc {
+                       compatible = "fsl,imx-osc", "fixed-clock";
+                       clock-frequency = <24000000>;
+               };
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&tzic>;
+               ranges;
+
+               ahb: ahb@40000000 {
+                       compatible = "fsl,ahb-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x40000000 0x60000000>;
+                       ranges;
+
+                       ipu@5e000000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx-ipuv3";
+                               reg = <0x5e000000 0x02000000>;
+                               interrupts = <10 11>;
+                               status = "disabled";
+                       };
+               };
+
+               aips@70000000 { /* AIPS1 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x70000000 0x10000000>;
+                       ranges;
+
+                       spba@70000000 {
+                               compatible = "fsl,spba-bus", "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x70000000 0x40000>;
+                               ranges;
+
+                               esdhc@70004000 { /* ESDHC1 */
+                                       compatible = "fsl,imx51-esdhc";
+                                       reg = <0x70004000 0x4000>;
+                                       interrupts = <1>;
+                                       status = "disabled";
+                               };
+
+                               esdhc@70008000 { /* ESDHC2 */
+                                       compatible = "fsl,imx51-esdhc";
+                                       reg = <0x70008000 0x4000>;
+                                       interrupts = <2>;
+                                       status = "disabled";
+                               };
+
+                               uart3: serial@7000c000 {
+                                       compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+                                       reg = <0x7000c000 0x4000>;
+                                       interrupts = <33>;
+                                       status = "disabled";
+                               };
+
+                               ecspi@70010000 { /* ECSPI1 */
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx51-ecspi";
+                                       reg = <0x70010000 0x4000>;
+                                       interrupts = <36>;
+                                       status = "disabled";
+                               };
+
+                               ssi2: ssi@70014000 {
+                                       compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+                                       reg = <0x70014000 0x4000>;
+                                       interrupts = <30>;
+                                       fsl,fifo-depth = <15>;
+                                       fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
+                                       status = "disabled";
+                               };
+
+                               esdhc@70020000 { /* ESDHC3 */
+                                       compatible = "fsl,imx51-esdhc";
+                                       reg = <0x70020000 0x4000>;
+                                       interrupts = <3>;
+                                       status = "disabled";
+                               };
+
+                               esdhc@70024000 { /* ESDHC4 */
+                                       compatible = "fsl,imx51-esdhc";
+                                       reg = <0x70024000 0x4000>;
+                                       interrupts = <4>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       usb@73f80000 {
+                               compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+                               reg = <0x73f80000 0x0200>;
+                               interrupts = <18>;
+                               status = "disabled";
+                       };
+
+                       usb@73f80200 {
+                               compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+                               reg = <0x73f80200 0x0200>;
+                               interrupts = <14>;
+                               status = "disabled";
+                       };
+
+                       usb@73f80400 {
+                               compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+                               reg = <0x73f80400 0x0200>;
+                               interrupts = <16>;
+                               status = "disabled";
+                       };
+
+                       usb@73f80600 {
+                               compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+                               reg = <0x73f80600 0x0200>;
+                               interrupts = <17>;
+                               status = "disabled";
+                       };
+
+                       gpio1: gpio@73f84000 {
+                               compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+                               reg = <0x73f84000 0x4000>;
+                               interrupts = <50 51>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio2: gpio@73f88000 {
+                               compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+                               reg = <0x73f88000 0x4000>;
+                               interrupts = <52 53>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio3: gpio@73f8c000 {
+                               compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+                               reg = <0x73f8c000 0x4000>;
+                               interrupts = <54 55>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       gpio4: gpio@73f90000 {
+                               compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+                               reg = <0x73f90000 0x4000>;
+                               interrupts = <56 57>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                       };
+
+                       keypad@73f94000 {
+                               compatible = "fsl,imx-keypad";
+                               reg = <0x73f94000 0x4000>;
+                               interrupts = <60>;
+                               status = "disabled";
+                       };
+
+                       wdog@73f98000 { /* WDOG1 */
+                               compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+                               reg = <0x73f98000 0x4000>;
+                               interrupts = <58>;
+                               status = "disabled";
+                       };
+
+                       wdog@73f9c000 { /* WDOG2 */
+                               compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+                               reg = <0x73f9c000 0x4000>;
+                               interrupts = <59>;
+                               status = "disabled";
+                       };
+
+                       iomuxc@73fa8000 {
+                               compatible = "fsl,imx51-iomuxc";
+                               reg = <0x73fa8000 0x4000>;
+
+                               audmux {
+                                       pinctrl_audmux_1: audmuxgrp-1 {
+                                               fsl,pins = <
+                                                       384 0x80000000  /* MX51_PAD_AUD3_BB_TXD__AUD3_TXD */
+                                                       386 0x80000000  /* MX51_PAD_AUD3_BB_RXD__AUD3_RXD */
+                                                       389 0x80000000  /* MX51_PAD_AUD3_BB_CK__AUD3_TXC */
+                                                       391 0x80000000  /* MX51_PAD_AUD3_BB_FS__AUD3_TXFS */
+                                               >;
+                                       };
+                               };
+
+                               fec {
+                                       pinctrl_fec_1: fecgrp-1 {
+                                               fsl,pins = <
+                                                       128 0x80000000  /* MX51_PAD_EIM_EB2__FEC_MDIO */
+                                                       134 0x80000000  /* MX51_PAD_EIM_EB3__FEC_RDATA1 */
+                                                       146 0x80000000  /* MX51_PAD_EIM_CS2__FEC_RDATA2 */
+                                                       152 0x80000000  /* MX51_PAD_EIM_CS3__FEC_RDATA3 */
+                                                       158 0x80000000  /* MX51_PAD_EIM_CS4__FEC_RX_ER */
+                                                       165 0x80000000  /* MX51_PAD_EIM_CS5__FEC_CRS */
+                                                       206 0x80000000  /* MX51_PAD_NANDF_RB2__FEC_COL */
+                                                       213 0x80000000  /* MX51_PAD_NANDF_RB3__FEC_RX_CLK */
+                                                       293 0x80000000  /* MX51_PAD_NANDF_D9__FEC_RDATA0 */
+                                                       298 0x80000000  /* MX51_PAD_NANDF_D8__FEC_TDATA0 */
+                                                       225 0x80000000  /* MX51_PAD_NANDF_CS2__FEC_TX_ER */
+                                                       231 0x80000000  /* MX51_PAD_NANDF_CS3__FEC_MDC */
+                                                       237 0x80000000  /* MX51_PAD_NANDF_CS4__FEC_TDATA1 */
+                                                       243 0x80000000  /* MX51_PAD_NANDF_CS5__FEC_TDATA2 */
+                                                       250 0x80000000  /* MX51_PAD_NANDF_CS6__FEC_TDATA3 */
+                                                       255 0x80000000  /* MX51_PAD_NANDF_CS7__FEC_TX_EN */
+                                                       260 0x80000000  /* MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK */
+                                               >;
+                                       };
+                               };
+
+                               ecspi1 {
+                                       pinctrl_ecspi1_1: ecspi1grp-1 {
+                                               fsl,pins = <
+                                                       398 0x185       /* MX51_PAD_CSPI1_MISO__ECSPI1_MISO */
+                                                       394 0x185       /* MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI */
+                                                       409 0x185       /* MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK */
+                                               >;
+                                       };
+                               };
+
+                               esdhc1 {
+                                       pinctrl_esdhc1_1: esdhc1grp-1 {
+                                               fsl,pins = <
+                                                       666 0x400020d5  /* MX51_PAD_SD1_CMD__SD1_CMD */
+                                                       669 0x20d5      /* MX51_PAD_SD1_CLK__SD1_CLK */
+                                                       672 0x20d5      /* MX51_PAD_SD1_DATA0__SD1_DATA0 */
+                                                       678 0x20d5      /* MX51_PAD_SD1_DATA1__SD1_DATA1 */
+                                                       684 0x20d5      /* MX51_PAD_SD1_DATA2__SD1_DATA2 */
+                                                       691 0x20d5      /* MX51_PAD_SD1_DATA3__SD1_DATA3 */
+                                               >;
+                                       };
+                               };
+
+                               esdhc2 {
+                                       pinctrl_esdhc2_1: esdhc2grp-1 {
+                                               fsl,pins = <
+                                                       704 0x400020d5  /* MX51_PAD_SD2_CMD__SD2_CMD */
+                                                       707 0x20d5      /* MX51_PAD_SD2_CLK__SD2_CLK */
+                                                       710 0x20d5      /* MX51_PAD_SD2_DATA0__SD2_DATA0 */
+                                                       712 0x20d5      /* MX51_PAD_SD2_DATA1__SD2_DATA1 */
+                                                       715 0x20d5      /* MX51_PAD_SD2_DATA2__SD2_DATA2 */
+                                                       719 0x20d5      /* MX51_PAD_SD2_DATA3__SD2_DATA3 */
+                                               >;
+                                       };
+                               };
+
+                               i2c2 {
+                                       pinctrl_i2c2_1: i2c2grp-1 {
+                                               fsl,pins = <
+                                                       449 0x400001ed  /* MX51_PAD_KEY_COL4__I2C2_SCL */
+                                                       454 0x400001ed  /* MX51_PAD_KEY_COL5__I2C2_SDA */
+                                               >;
+                                       };
+                               };
+
+                               uart1 {
+                                       pinctrl_uart1_1: uart1grp-1 {
+                                               fsl,pins = <
+                                                       413 0x1c5       /* MX51_PAD_UART1_RXD__UART1_RXD */
+                                                       416 0x1c5       /* MX51_PAD_UART1_TXD__UART1_TXD */
+                                                       418 0x1c5       /* MX51_PAD_UART1_RTS__UART1_RTS */
+                                                       420 0x1c5       /* MX51_PAD_UART1_CTS__UART1_CTS */
+                                               >;
+                                       };
+                               };
+
+                               uart2 {
+                                       pinctrl_uart2_1: uart2grp-1 {
+                                               fsl,pins = <
+                                                       423 0x1c5       /* MX51_PAD_UART2_RXD__UART2_RXD */
+                                                       426 0x1c5       /* MX51_PAD_UART2_TXD__UART2_TXD */
+                                               >;
+                                       };
+                               };
+
+                               uart3 {
+                                       pinctrl_uart3_1: uart3grp-1 {
+                                               fsl,pins = <
+                                                       54 0x1c5        /* MX51_PAD_EIM_D25__UART3_RXD */
+                                                       59 0x1c5        /* MX51_PAD_EIM_D26__UART3_TXD */
+                                                       65 0x1c5        /* MX51_PAD_EIM_D27__UART3_RTS */
+                                                       49 0x1c5        /* MX51_PAD_EIM_D24__UART3_CTS */
+                                               >;
+                                       };
+                               };
+                       };
+
+                       pwm@73fb4000 {
+                               compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
+                               reg = <0x73fb4000 0x4000>;
+                               interrupts = <61>;
+                               status = "disabled";
+                       };
+
+                       pwm@73fb8000 {
+                               compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
+                               reg = <0x73fb8000 0x4000>;
+                               interrupts = <94>;
+                               status = "disabled";
+                       };
+
+                       uart1: serial@73fbc000 {
+                               compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+                               reg = <0x73fbc000 0x4000>;
+                               interrupts = <31>;
+                               status = "disabled";
+                       };
+
+                       uart2: serial@73fc0000 {
+                               compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+                               reg = <0x73fc0000 0x4000>;
+                               interrupts = <32>;
+                               status = "disabled";
+                       };
+               };
+
+               aips@80000000 { /* AIPS2 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x80000000 0x10000000>;
+                       ranges;
+
+                       ecspi@83fac000 { /* ECSPI2 */
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx51-ecspi";
+                               reg = <0x83fac000 0x4000>;
+                               interrupts = <37>;
+                               status = "disabled";
+                       };
+
+                       sdma@83fb0000 {
+                               compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
+                               reg = <0x83fb0000 0x4000>;
+                               interrupts = <6>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
+                       };
+
+                       cspi@83fc0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
+                               reg = <0x83fc0000 0x4000>;
+                               interrupts = <38>;
+                               status = "disabled";
+                       };
+
+                       i2c@83fc4000 { /* I2C2 */
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx51-i2c", "fsl,imx1-i2c";
+                               reg = <0x83fc4000 0x4000>;
+                               interrupts = <63>;
+                               status = "disabled";
+                       };
+
+                       i2c@83fc8000 { /* I2C1 */
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx51-i2c", "fsl,imx1-i2c";
+                               reg = <0x83fc8000 0x4000>;
+                               interrupts = <62>;
+                               status = "disabled";
+                       };
+
+                       ssi1: ssi@83fcc000 {
+                               compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+                               reg = <0x83fcc000 0x4000>;
+                               interrupts = <29>;
+                               fsl,fifo-depth = <15>;
+                               fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
+                               status = "disabled";
+                       };
+
+                       audmux@83fd0000 {
+                               compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
+                               reg = <0x83fd0000 0x4000>;
+                               ssi-ports = <0 1 2>;
+                               ext-ports = <3 4 5 6>;
+                               status = "disabled";
+                       };
+
+                       nand@83fdb000 {
+                               compatible = "fsl,imx51-nand";
+                               reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
+                               interrupts = <8>;
+                               status = "disabled";
+                       };
+
+                       ssi3: ssi@83fe8000 {
+                               compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+                               reg = <0x83fe8000 0x4000>;
+                               interrupts = <96>;
+                               fsl,fifo-depth = <15>;
+                               fsl,ssi-dma-events = <47 46 37 35>; /* TX0 RX0 TX1 RX1 */
+                               status = "disabled";
+                       };
+
+                       fec0: ethernet@83fec000 {
+                               compatible = "fsl,imx51-fec", "fsl,imx27-fec";
+                               reg = <0x83fec000 0x4000>;
+                               interrupts = <87>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/dts/mx53.dtsi b/arch/arm/dts/mx53.dtsi
new file mode 100644 (file)
index 0000000..e726be0
--- /dev/null
@@ -0,0 +1,615 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       aliases {
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               serial4 = &uart5;
+               gpio1 = &gpio1;
+               gpio2 = &gpio2;
+               gpio3 = &gpio3;
+               gpio4 = &gpio4;
+               gpio5 = &gpio5;
+               gpio6 = &gpio6;
+               gpio7 = &gpio7;
+       };
+
+       tzic: tz-interrupt-controller@0fffc000 {
+               compatible = "fsl,imx53-tzic", "fsl,tzic";
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               reg = <0x0fffc000 0x4000>;
+       };
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ckil {
+                       compatible = "fsl,imx-ckil", "fixed-clock";
+                       clock-frequency = <32768>;
+               };
+
+               ckih1 {
+                       compatible = "fsl,imx-ckih1", "fixed-clock";
+                       clock-frequency = <22579200>;
+               };
+
+               ckih2 {
+                       compatible = "fsl,imx-ckih2", "fixed-clock";
+                       clock-frequency = <0>;
+               };
+
+               osc {
+                       compatible = "fsl,imx-osc", "fixed-clock";
+                       clock-frequency = <24000000>;
+               };
+       };
+
+       soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "simple-bus";
+               interrupt-parent = <&tzic>;
+               ranges;
+
+               extmc@00000000 {
+                       compatible = "fsl,extmc", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x00000000 0x40000000>;
+                       ranges;
+
+                       sata@10000000 {
+                               compatible = "fsl,imx53-sata", "fsl,imx-ahci";
+                               reg = <0x10000000 0x00004000>;
+                               interrupts = <28>;
+                               status = "disabled";
+                       };
+
+                       ipu@1e000000 {
+                               compatible = "fsl,imx-ipuv3";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x1e000000 0x02000000>;
+                               interrupts = <10 11>;
+                               status = "disabled";
+                       };
+               };
+
+               aips@50000000 { /* AIPS1 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x50000000 0x10000000>;
+                       ranges;
+
+                       spba@50000000 {
+                               compatible = "fsl,spba-bus", "simple-bus";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x50000000 0x40000>;
+                               ranges;
+
+                               esdhc@50004000 { /* ESDHC1 */
+                                       compatible = "fsl,imx53-esdhc";
+                                       reg = <0x50004000 0x4000>;
+                                       interrupts = <1>;
+                                       status = "disabled";
+                               };
+
+                               esdhc@50008000 { /* ESDHC2 */
+                                       compatible = "fsl,imx53-esdhc";
+                                       reg = <0x50008000 0x4000>;
+                                       interrupts = <2>;
+                                       status = "disabled";
+                               };
+
+                               uart3: uart@5000c000 {
+                                       compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+                                       reg = <0x5000c000 0x4000>;
+                                       interrupts = <33>;
+                                       status = "disabled";
+                               };
+
+                               ecspi@50010000 { /* ECSPI1 */
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x50010000 0x4000>;
+                                       interrupts = <36>;
+                                       status = "disabled";
+                               };
+
+                               ssi2: ssi@50014000 {
+                                       compatible = "fsl,imx-ssi";
+                                       reg = <0x50014000 0x4000>;
+                                       interrupts = <30>;
+                                       status = "disabled";
+                               };
+
+                               esdhc@50020000 { /* ESDHC3 */
+                                       compatible = "fsl,imx53-esdhc";
+                                       reg = <0x50020000 0x4000>;
+                                       interrupts = <3>;
+                                       status = "disabled";
+                               };
+
+                               esdhc@50024000 { /* ESDHC4 */
+                                       compatible = "fsl,imx53-esdhc";
+                                       reg = <0x50024000 0x4000>;
+                                       interrupts = <4>;
+                                       status = "disabled";
+                               };
+                       };
+
+                       imxotg@53f80000 {
+                               compatible = "fsl,imx-otg";
+                               reg = <0x53f80000 0x200>;
+                               interrupts = <18>;
+                               status = "disabled";
+
+                               phy-mode = "utmi-wide";
+                               host-device-name = "mxc-ehci";
+                               host-device-id = <0>;
+                               gadget-device-name = "fsl-usb2-udc";
+                       };
+
+                       imxotg@53f80200 {
+                               compatible = "fsl,imx-otg";
+                               reg = <0x53f80200 0x200>;
+                               interrupts = <14>;
+                               status = "disabled";
+
+                               phy-mode = "utmi-wide";
+                               host-device-name = "mxc-ehci";
+                               host-device-id = <1>;
+                       };
+
+                       mxc-ehci@53f80400 {
+                               compatible = "fsl,mxc-ehci";
+                               reg = <0x53f80400 0x200>;
+                               interrupts = <16>;
+                               status = "disabled";
+                       };
+
+                       mxc-ehci@53f80600 {
+                               compatible = "fsl,mxc-ehci";
+                               reg = <0x53f80600 0x200>;
+                               interrupts = <17>;
+                               status = "disabled";
+                       };
+
+                       imx-usb-phy@53f80800 {
+                               compatible = "fsl,imx53-usb-phy", "fsl,imx-usb-phy";
+                               reg = <0x53f80800 0x200>;
+                               status = "disabled";
+                       };
+
+                       gpio1: gpio@53f84000 {
+                               compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+                               reg = <0x53f84000 0x4000>;
+                               interrupts = <50 51>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio2: gpio@53f88000 {
+                               compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+                               reg = <0x53f88000 0x4000>;
+                               interrupts = <52 53>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio3: gpio@53f8c000 {
+                               compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+                               reg = <0x53f8c000 0x4000>;
+                               interrupts = <54 55>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio4: gpio@53f90000 {
+                               compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+                               reg = <0x53f90000 0x4000>;
+                               interrupts = <56 57>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       keypad@53f94000 {
+                               compatible = "fsl,imx-keypad";
+                               reg = <0x53f94000 0x4000>;
+                               interrupts = <60>;
+                               status = "disabled";
+                       };
+
+                       wdog@53f98000 { /* WDOG1 */
+                               compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
+                               reg = <0x53f98000 0x4000>;
+                               interrupts = <58>;
+                               status = "disabled";
+                       };
+
+                       wdog@53f9c000 { /* WDOG2 */
+                               compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
+                               reg = <0x53f9c000 0x4000>;
+                               interrupts = <59>;
+                               status = "disabled";
+                       };
+
+                       iomuxc@53fa8000 {
+                               compatible = "fsl,imx53-iomuxc";
+                               reg = <0x53fa8000 0x4000>;
+
+                               audmux {
+                                       pinctrl_audmux_1: audmuxgrp-1 {
+                                               fsl,pins = <
+                                                       10 0x80 /* MX53_PAD_KEY_COL0__AUDMUX_AUD5_TXC */
+                                                       17 0x80 /* MX53_PAD_KEY_ROW0__AUDMUX_AUD5_TXD */
+                                                       23 0x80 /* MX53_PAD_KEY_COL1__AUDMUX_AUD5_TXFS */
+                                                       30 0x80 /* MX53_PAD_KEY_ROW1__AUDMUX_AUD5_RXD */
+                                               >;
+                                       };
+                               };
+
+                               fec {
+                                       pinctrl_fec_1: fecgrp-1 {
+                                               fsl,pins = <
+                                                       820 0x80        /* MX53_PAD_FEC_MDC__FEC_MDC */
+                                                       779 0x80        /* MX53_PAD_FEC_MDIO__FEC_MDIO */
+                                                       786 0x80        /* MX53_PAD_FEC_REF_CLK__FEC_TX_CLK */
+                                                       791 0x80        /* MX53_PAD_FEC_RX_ER__FEC_RX_ER */
+                                                       796 0x80        /* MX53_PAD_FEC_CRS_DV__FEC_RX_DV */
+                                                       799 0x80        /* MX53_PAD_FEC_RXD1__FEC_RDATA_1 */
+                                                       804 0x80        /* MX53_PAD_FEC_RXD0__FEC_RDATA_0 */
+                                                       808 0x80        /* MX53_PAD_FEC_TX_EN__FEC_TX_EN */
+                                                       811 0x80        /* MX53_PAD_FEC_TXD1__FEC_TDATA_1 */
+                                                       816 0x80        /* MX53_PAD_FEC_TXD0__FEC_TDATA_0 */
+                                               >;
+                                       };
+                               };
+
+                               ecspi1 {
+                                       pinctrl_ecspi1_1: ecspi1grp-1 {
+                                               fsl,pins = <
+                                                       433 0x80        /* MX53_PAD_EIM_D16__ECSPI1_SCLK */
+                                                       439 0x80        /* MX53_PAD_EIM_D17__ECSPI1_MISO */
+                                                       445 0x80        /* MX53_PAD_EIM_D18__ECSPI1_MOSI */
+                                               >;
+                                       };
+                               };
+
+                               esdhc1 {
+                                       pinctrl_esdhc1_1: esdhc1grp-1 {
+                                               fsl,pins = <
+                                                       995  0x1d4      /* MX53_PAD_SD1_DATA0__ESDHC1_DAT0 */
+                                                       1000 0x1d4      /* MX53_PAD_SD1_DATA1__ESDHC1_DAT1 */
+                                                       1010 0x1d4      /* MX53_PAD_SD1_DATA2__ESDHC1_DAT2 */
+                                                       1024 0x1c4      /* MX53_PAD_SD1_DATA3__ESDHC1_DAT3 */
+                                                       1005 0x1d4      /* MX53_PAD_SD1_CMD__ESDHC1_CMD */
+                                                       1018 0x1d4      /* MX53_PAD_SD1_CLK__ESDHC1_CLK */
+                                               >;
+                                       };
+
+                                       pinctrl_esdhc1_2: esdhc1grp-2 {
+                                               fsl,pins = <
+                                                       995  0x1d4      /* MX53_PAD_SD1_DATA0__ESDHC1_DAT0 */
+                                                       1000 0x1d4      /* MX53_PAD_SD1_DATA1__ESDHC1_DAT1 */
+                                                       1010 0x1d4      /* MX53_PAD_SD1_DATA2__ESDHC1_DAT2 */
+                                                       1024 0x1c4      /* MX53_PAD_SD1_DATA3__ESDHC1_DAT3 */
+                                                       941  0x1d4      /* MX53_PAD_PATA_DATA8__ESDHC1_DAT4 */
+                                                       948  0x1d4      /* MX53_PAD_PATA_DATA9__ESDHC1_DAT5 */
+                                                       955  0x1d4      /* MX53_PAD_PATA_DATA10__ESDHC1_DAT6 */
+                                                       962  0x1d4      /* MX53_PAD_PATA_DATA11__ESDHC1_DAT7 */
+                                                       1005 0x1d4      /* MX53_PAD_SD1_CMD__ESDHC1_CMD */
+                                                       1018 0x1d4      /* MX53_PAD_SD1_CLK__ESDHC1_CLK */
+                                               >;
+                                       };
+                               };
+
+                               esdhc2 {
+                                       pinctrl_esdhc2_1: esdhc2grp-1 {
+                                               fsl,pins = <
+                                                       1038 0x1d5      /* MX53_PAD_SD2_CMD__ESDHC2_CMD */
+                                                       1032 0x1d5      /* MX53_PAD_SD2_CLK__ESDHC2_CLK */
+                                                       1062 0x1d5      /* MX53_PAD_SD2_DATA0__ESDHC2_DAT0 */
+                                                       1056 0x1d5      /* MX53_PAD_SD2_DATA1__ESDHC2_DAT1 */
+                                                       1050 0x1d5      /* MX53_PAD_SD2_DATA2__ESDHC2_DAT2 */
+                                                       1044 0x1d5      /* MX53_PAD_SD2_DATA3__ESDHC2_DAT3 */
+                                               >;
+                                       };
+                               };
+
+                               esdhc3 {
+                                       pinctrl_esdhc3_1: esdhc3grp-1 {
+                                               fsl,pins = <
+                                                       943 0x1d5       /* MX53_PAD_PATA_DATA8__ESDHC3_DAT0 */
+                                                       950 0x1d5       /* MX53_PAD_PATA_DATA9__ESDHC3_DAT1 */
+                                                       957 0x1d5       /* MX53_PAD_PATA_DATA10__ESDHC3_DAT2 */
+                                                       964 0x1d5       /* MX53_PAD_PATA_DATA11__ESDHC3_DAT3 */
+                                                       893 0x1d5       /* MX53_PAD_PATA_DATA0__ESDHC3_DAT4 */
+                                                       900 0x1d5       /* MX53_PAD_PATA_DATA1__ESDHC3_DAT5 */
+                                                       906 0x1d5       /* MX53_PAD_PATA_DATA2__ESDHC3_DAT6 */
+                                                       912 0x1d5       /* MX53_PAD_PATA_DATA3__ESDHC3_DAT7 */
+                                                       857 0x1d5       /* MX53_PAD_PATA_RESET_B__ESDHC3_CMD */
+                                                       863 0x1d5       /* MX53_PAD_PATA_IORDY__ESDHC3_CLK */
+                                               >;
+                                       };
+                               };
+
+                               i2c1 {
+                                       pinctrl_i2c1_1: i2c1grp-1 {
+                                               fsl,pins = <
+                                                       333 0xc0        /* MX53_PAD_CSI0_DAT8__I2C1_SDA */
+                                                       341 0xc0        /* MX53_PAD_CSI0_DAT9__I2C1_SCL */
+                                               >;
+                                       };
+
+                                       pinctrl_i2c1_2: i2c1grp-2 {
+                                               fsl,pins = <
+                                                       529 0xc0        /* MX53_PAD_EIM_D28__I2C1_SDA */
+                                                       469 0xc0        /* MX53_PAD_EIM_D21__I2C1_SCL */
+                                               >;
+                                       };
+                               };
+
+                               i2c2 {
+                                       pinctrl_i2c2_1: i2c2grp-1 {
+                                               fsl,pins = <
+                                                       61 0xc0         /* MX53_PAD_KEY_ROW3__I2C2_SDA */
+                                                       53 0xc0         /* MX53_PAD_KEY_COL3__I2C2_SCL */
+                                               >;
+                                       };
+                               };
+
+                               i2c3 {
+                                       pinctrl_i2c3_1: i2c3grp-1 {
+                                               fsl,pins = <
+                                                       1102 0xc0       /* MX53_PAD_GPIO_6__I2C3_SDA */
+                                                       1094 0xc0       /* MX53_PAD_GPIO_3__I2C3_SCL */
+                                               >;
+                                       };
+                               };
+
+                               uart1 {
+                                       pinctrl_uart1_1: uart1grp-1 {
+                                               fsl,pins = <
+                                                       346 0x1c5       /* MX53_PAD_CSI0_DAT10__UART1_TXD_MUX */
+                                                       354 0x1c5       /* MX53_PAD_CSI0_DAT11__UART1_RXD_MUX */
+                                               >;
+                                       };
+
+                                       pinctrl_uart1_2: uart1grp-2 {
+                                               fsl,pins = <
+                                                       828 0x1c5       /* MX53_PAD_PATA_DIOW__UART1_TXD_MUX */
+                                                       832 0x1c5       /* MX53_PAD_PATA_DMACK__UART1_RXD_MUX */
+                                               >;
+                                       };
+                               };
+
+                               uart2 {
+                                       pinctrl_uart2_1: uart2grp-1 {
+                                               fsl,pins = <
+                                                       841 0x1c5       /* MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX */
+                                                       836 0x1c5       /* MX53_PAD_PATA_DMARQ__UART2_TXD_MUX */
+                                               >;
+                                       };
+                               };
+
+                               uart3 {
+                                       pinctrl_uart3_1: uart3grp-1 {
+                                               fsl,pins = <
+                                                       884 0x1c5       /* MX53_PAD_PATA_CS_0__UART3_TXD_MUX */
+                                                       888 0x1c5       /* MX53_PAD_PATA_CS_1__UART3_RXD_MUX */
+                                                       875 0x1c5       /* MX53_PAD_PATA_DA_1__UART3_CTS */
+                                                       880 0x1c5       /* MX53_PAD_PATA_DA_2__UART3_RTS */
+                                               >;
+                                       };
+                               };
+                       };
+                       pwm@53fb4000 {
+                               compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
+                               reg = <0x53fb4000 0x4000>;
+                               interrupts = <61>;
+                               status = "disabled";
+                       };
+
+                       pwm@53fb8000 {
+                               compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
+                               reg = <0x53fb8000 0x4000>;
+                               interrupts = <94>;
+                               status = "disabled";
+                       };
+
+                       uart1: uart@53fbc000 {
+                               compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+                               reg = <0x53fbc000 0x4000>;
+                               interrupts = <31>;
+                               status = "disabled";
+                       };
+
+                       uart2: uart@53fc0000 {
+                               compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+                               reg = <0x53fc0000 0x4000>;
+                               interrupts = <32>;
+                               status = "disabled";
+                       };
+
+                       can1: flexcan@53fc8000 {
+                               compatible = "fsl,p1010-flexcan";
+                               reg = <0x53fc8000 0x4000>;
+                               interrupts = <82>;
+                               status = "disabled";
+                       };
+
+                       can2: flexcan@53fcc000 {
+                               compatible = "fsl,p1010-flexcan";
+                               reg = <0x53fcc000 0x4000>;
+                               interrupts = <83>;
+                               status = "disabled";
+                       };
+
+                       gpio5: gpio@53fdc000 {
+                               compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+                               reg = <0x53fdc000 0x4000>;
+                               interrupts = <103 104>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio6: gpio@53fe0000 {
+                               compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+                               reg = <0x53fe0000 0x4000>;
+                               interrupts = <105 106>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       gpio7: gpio@53fe4000 {
+                               compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+                               reg = <0x53fe4000 0x4000>;
+                               interrupts = <107 108>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                       };
+
+                       i2c@53fec000 { /* I2C3 */
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+                               reg = <0x53fec000 0x4000>;
+                               interrupts = <64>;
+                               status = "disabled";
+                       };
+
+                       uart4: uart@53ff0000 {
+                               compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+                               reg = <0x53ff0000 0x4000>;
+                               interrupts = <13>;
+                               status = "disabled";
+                       };
+               };
+
+               aips@60000000 { /* AIPS2 */
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x60000000 0x10000000>;
+                       ranges;
+
+                       uart5: uart@63f90000 {
+                               compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+                               reg = <0x63f90000 0x4000>;
+                               interrupts = <86>;
+                               status = "disabled";
+                       };
+
+                       ecspi@63fac000 { /* ECSPI2 */
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+                               reg = <0x63fac000 0x4000>;
+                               interrupts = <37>;
+                               status = "disabled";
+                       };
+
+                       sdma@63fb0000 {
+                               compatible = "fsl,imx53-sdma", "fsl,imx35-sdma";
+                               reg = <0x63fb0000 0x4000>;
+                               interrupts = <6>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
+                       };
+
+                       cspi@63fc0000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
+                               reg = <0x63fc0000 0x4000>;
+                               interrupts = <38>;
+                               status = "disabled";
+                       };
+
+                       i2c@63fc4000 { /* I2C2 */
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+                               reg = <0x63fc4000 0x4000>;
+                               interrupts = <63>;
+                               status = "disabled";
+                       };
+
+                       i2c@63fc8000 { /* I2C1 */
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+                               reg = <0x63fc8000 0x4000>;
+                               interrupts = <62>;
+                               status = "disabled";
+                       };
+
+                       ssi1: ssi@63fcc000 {
+                               compatible = "fsl,imx-ssi";
+                               reg = <0x63fcc000 0x4000>;
+                               interrupts = <29>;
+                               status = "disabled";
+                       };
+
+                       audmux@63fd0000 {
+                               compatible = "fsl,imx53-audmux", "fsl,imx31-audmux";
+                               reg = <0x63fd0000 0x4000>;
+                               status = "disabled";
+                       };
+
+                       nand@63fdb000 {
+                               compatible = "fsl,imx53-nand", "mxc_nand";
+                               reg = <0xf7ff0000 0x10000>, <0x63fdb000 0x4000>;
+                               interrupts = <8>;
+                               status = "disabled";
+                       };
+
+                       ssi3: ssi@63fe8000 {
+                               compatible = "fsl,imx-ssi";
+                               reg = <0x63fe8000 0x4000>;
+                               interrupts = <96>;
+                               status = "disabled";
+                       };
+
+                       ethernet@63fec000 {
+                               compatible = "fsl,imx53-fec", "fsl,imx25-fec";
+                               reg = <0x63fec000 0x4000>;
+                               interrupts = <87>;
+                               status = "disabled";
+                       };
+               };
+       };
+};
diff --git a/arch/arm/dts/mx6dl.dtsi b/arch/arm/dts/mx6dl.dtsi
new file mode 100644 (file)
index 0000000..10905f1
--- /dev/null
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/include/ "imx6qdl.dtsi"
+
+/ {
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       compatible = "arm,cortex-a9";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               792000  1150000
+                               396000  950000
+                       >;
+                       clock-latency = <61036>; /* two CLK32 periods */
+                       clocks = <&clks 104>, <&clks 6>, <&clks 16>,
+                                <&clks 17>, <&clks 170>;
+                       clock-names = "arm", "pll2_pfd2_396m", "step",
+                                     "pll1_sw", "pll1_sys";
+                       arm-supply = <&reg_arm>;
+                       pu-supply = <&reg_pu>;
+                       soc-supply = <&reg_soc>;
+               };
+
+               cpu@1 {
+                       compatible = "arm,cortex-a9";
+                       reg = <1>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       soc {
+               aips-bus@02000000 { /* AIPS1 */
+                       spba-bus@02000000 {
+                               ecspi5: ecspi@02018000 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,iMX6DL-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x02018000 0x4000>;
+                                       interrupts = <0 35 0x04>;
+                                       clocks = <&clks 116>, <&clks 116>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+                       };
+
+                       iomuxc: iomuxc@020e0000 {
+                               compatible = "fsl,iMX6DL-iomuxc";
+                               reg = <0x020e0000 0x4000>;
+
+                               /* shared pinctrl settings */
+                               audmux {
+                                       pinctrl_audmux_1: audmux-1 {
+                                               fsl,pins = <
+                                                       18   0x80000000 /* MX6DL_PAD_SD2_DAT0__AUDMUX_AUD4_RXD */
+                                                       1586 0x80000000 /* MX6DL_PAD_SD2_DAT3__AUDMUX_AUD4_TXC */
+                                                       11   0x80000000 /* MX6DL_PAD_SD2_DAT2__AUDMUX_AUD4_TXD */
+                                                       3    0x80000000 /* MX6DL_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */
+                                               >;
+                                       };
+                               };
+
+                               ecspi1 {
+                                       pinctrl_ecspi1_1: ecspi1grp-1 {
+                                               fsl,pins = <
+                                                       101 0x100b1     /* MX6DL_PAD_EIM_D17__ECSPI1_MISO */
+                                                       109 0x100b1     /* MX6DL_PAD_EIM_D18__ECSPI1_MOSI */
+                                                       94  0x100b1     /* MX6DL_PAD_EIM_D16__ECSPI1_SCLK */
+                                               >;
+                                       };
+                               };
+
+                               enet {
+                                       pinctrl_enet_1: enetgrp-1 {
+                                               fsl,pins = <
+                                                       695 0x1b0b0     /* MX6DL_PAD_ENET_MDIO__ENET_MDIO */
+                                                       756 0x1b0b0     /* MX6DL_PAD_ENET_MDC__ENET_MDC */
+                                                       24  0x1b0b0     /* MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC */
+                                                       30  0x1b0b0     /* MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0 */
+                                                       34  0x1b0b0     /* MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1 */
+                                                       39  0x1b0b0     /* MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2 */
+                                                       44  0x1b0b0     /* MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3 */
+                                                       56  0x1b0b0     /* MX6DL_PAD_RGMII_TX_CTL__RGMII_TX_CTL */
+                                                       702 0x1b0b0     /* MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK */
+                                                       74  0x1b0b0     /* MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC */
+                                                       52  0x1b0b0     /* MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0 */
+                                                       61  0x1b0b0     /* MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1 */
+                                                       66  0x1b0b0     /* MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2 */
+                                                       70  0x1b0b0     /* MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3 */
+                                                       48  0x1b0b0     /* MX6DL_PAD_RGMII_RX_CTL__RGMII_RX_CTL */
+                                                       1033 0x4001b0a8 /* MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT*/
+                                               >;
+                                       };
+
+                                       pinctrl_enet_2: enetgrp-2 {
+                                               fsl,pins = <
+                                                       890 0x1b0b0     /* MX6DL_PAD_KEY_COL1__ENET_MDIO */
+                                                       909 0x1b0b0     /* MX6DL_PAD_KEY_COL2__ENET_MDC */
+                                                       24  0x1b0b0     /* MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC */
+                                                       30  0x1b0b0     /* MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0 */
+                                                       34  0x1b0b0     /* MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1 */
+                                                       39  0x1b0b0     /* MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2 */
+                                                       44  0x1b0b0     /* MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3 */
+                                                       56  0x1b0b0     /* MX6DL_PAD_RGMII_TX_CTL__RGMII_TX_CTL */
+                                                       702 0x1b0b0     /* MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK */
+                                                       74  0x1b0b0     /* MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC */
+                                                       52  0x1b0b0     /* MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0 */
+                                                       61  0x1b0b0     /* MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1 */
+                                                       66  0x1b0b0     /* MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2 */
+                                                       70  0x1b0b0     /* MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3 */
+                                                       48  0x1b0b0     /* MX6DL_PAD_RGMII_RX_CTL__RGMII_RX_CTL */
+                                               >;
+                                       };
+                               };
+
+                               gpmi-nand {
+                                       pinctrl_gpmi_nand_1: gpmi-nand-1 {
+                                               fsl,pins = <
+                                                       1328 0xb0b1     /* MX6DL_PAD_NANDF_CLE__RAWNAND_CLE */
+                                                       1336 0xb0b1     /* MX6DL_PAD_NANDF_ALE__RAWNAND_ALE */
+                                                       1344 0xb0b1     /* MX6DL_PAD_NANDF_WP_B__RAWNAND_RESETN */
+                                                       1352 0xb000     /* MX6DL_PAD_NANDF_RB0__RAWNAND_READY0 */
+                                                       1360 0xb0b1     /* MX6DL_PAD_NANDF_CS0__RAWNAND_CE0N */
+                                                       1365 0xb0b1     /* MX6DL_PAD_NANDF_CS1__RAWNAND_CE1N */
+                                                       1371 0xb0b1     /* MX6DL_PAD_NANDF_CS2__RAWNAND_CE2N */
+                                                       1378 0xb0b1     /* MX6DL_PAD_NANDF_CS3__RAWNAND_CE3N */
+                                                       1387 0xb0b1     /* MX6DL_PAD_SD4_CMD__RAWNAND_RDN */
+                                                       1393 0xb0b1     /* MX6DL_PAD_SD4_CLK__RAWNAND_WRN */
+                                                       1397 0xb0b1     /* MX6DL_PAD_NANDF_D0__RAWNAND_D0 */
+                                                       1405 0xb0b1     /* MX6DL_PAD_NANDF_D1__RAWNAND_D1 */
+                                                       1413 0xb0b1     /* MX6DL_PAD_NANDF_D2__RAWNAND_D2 */
+                                                       1421 0xb0b1     /* MX6DL_PAD_NANDF_D3__RAWNAND_D3 */
+                                                       1429 0xb0b1     /* MX6DL_PAD_NANDF_D4__RAWNAND_D4 */
+                                                       1437 0xb0b1     /* MX6DL_PAD_NANDF_D5__RAWNAND_D5 */
+                                                       1445 0xb0b1     /* MX6DL_PAD_NANDF_D6__RAWNAND_D6 */
+                                                       1453 0xb0b1     /* MX6DL_PAD_NANDF_D7__RAWNAND_D7 */
+                                                       1463 0x00b1     /* MX6DL_PAD_SD4_DAT0__RAWNAND_DQS */
+                                               >;
+                                       };
+                               };
+
+                               i2c1 {
+                                       pinctrl_i2c1_1: i2c1grp-1 {
+                                               fsl,pins = <
+                                                       137 0x4001b8b1  /* MX6DL_PAD_EIM_D21__I2C1_SCL */
+                                                       196 0x4001b8b1  /* MX6DL_PAD_EIM_D28__I2C1_SDA */
+                                               >;
+                                       };
+                               };
+
+                               uart1 {
+                                       pinctrl_uart1_1: uart1grp-1 {
+                                               fsl,pins = <
+                                                       1140 0x1b0b1    /* MX6DL_PAD_CSI0_DAT10__UART1_TXD */
+                                                       1148 0x1b0b1    /* MX6DL_PAD_CSI0_DAT11__UART1_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart1_2: uart1-grp-2 {
+                                               fsl,pins = <
+                                                       120  0x1b0b1    /* MX6DL_PAD_EIM_D19__UART1_CTS */
+                                                       128  0x1b0b1    /* MX6DL_PAD_EIM_D20__UART1_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart1_3: uart1grp-3 {
+                                               fsl,pins = <
+                                                       1242 0x1b0b1    /* MX6DL_PAD_SD3_DAT7__UART1_TXD */
+                                                       1250 0x1b0b1    /* MX6DL_PAD_SD3_DAT6__UART1_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart1_4: uart1-grp-4 {
+                                               fsl,pins = <
+                                                       1290 0x1b0b1    /* MX6DL_PAD_SD3_DAT0__UART1_CTS */
+                                                       1298 0x1b0b1    /* MX6DL_PAD_SD3_DAT1__UART1_RTS */
+                                               >;
+                                       };
+                               };
+
+                               uart2 {
+                                       pinctrl_uart2_1: uart2grp-1 {
+                                               fsl,pins = <
+                                                       183  0x1b0b1    /* MX6DL_PAD_EIM_D26__UART2_TXD */
+                                                       191  0x1b0b1    /* MX6DL_PAD_EIM_D27__UART2_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart2_2: uart2grp-2 {
+                                               fsl,pins = <
+                                                       199  0x1b0b1    /* MX6DL_PAD_EIM_D28__UART2_CTS */
+                                                       206  0x1b0b1    /* MX6DL_PAD_EIM_D29__UART2_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart2_3: uart2grp-3 {
+                                               fsl,pins = <
+                                                       1258 0x1b0b1    /* MX6DL_PAD_SD3_DAT5__UART2_TXD */
+                                                       1266 0x1b0b1    /* MX6DL_PAD_SD3_DAT6__UART2_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart2_4: uart2grp-4 {
+                                               fsl,pins = <
+                                                       1274 0x1b0b1    /* MX6DL_PAD_SD3_CMD__UART2_CTS */
+                                                       1282 0x1b0b1    /* MX6DL_PAD_SD3_CLK__UART2_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart2_5: uart2grp-5 {
+                                               fsl,pins = <
+                                                       1518 0x1b0b1    /* MX6DL_PAD_SD4_DAT7__UART2_TXD */
+                                                       1494 0x1b0b1    /* MX6DL_PAD_SD4_DAT4__UART2_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart2_6: uart2grp-6 {
+                                               fsl,pins = <
+                                                       1510 0x1b0b1    /* MX6DL_PAD_SD4_DAT6__UART2_CTS */
+                                                       1502 0x1b0b1    /* MX6DL_PAD_SD4_DAT5__UART2_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart2_7: uart2grp-7 {
+                                               fsl,pins = <
+                                                       1019 0x1b0b1    /* MX6DL_PAD_GPIO_7__UART2_TXD */
+                                                       1027 0x1b0b1    /* MX6DL_PAD_GPIO_8__UART2_RXD */
+                                               >;
+                                       };
+                               };
+
+                               uart3 {
+                                       pinctrl_uart3_1: uart3grp-1 {
+                                               fsl,pins = <
+                                                       165  0x1b0b1    /* MX6DL_PAD_EIM_D24__UART3_TXD */
+                                                       173  0x1b0b1    /* MX6DL_PAD_EIM_D25__UART3_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart3_2: uart3grp-2 {
+                                               fsl,pins = <
+                                                       149  0x1b0b1    /* MX6DL_PAD_EIM_D23__UART3_CTS */
+                                                       157  0x1b0b1    /* MX6DL_PAD_EIM_EB3__UART3_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart3_3: uart3grp-3 {
+                                               fsl,pins = <
+                                                       1388 0x1b0b1    /* MX6DL_PAD_SD4_CMD__UART3_TXD */
+                                                       1394 0x1b0b1    /* MX6DL_PAD_SD4_CLK__UART3_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart3_4: uart3grp-4 {
+                                               fsl,pins = <
+                                                       1313 0x1b0b1    /* MX6DL_PAD_SD3_DAT3__UART3_CTS */
+                                                       1321 0x1b0b1    /* MX6DL_PAD_SD3_RST__UART3_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart3_5: uart3grp-5 {
+                                               fsl,pins = <
+                                                       214  0x1b0b1    /* MX6DL_PAD_EIM_D30__UART3_CTS */
+                                                       222  0x1b0b1    /* MX6DL_PAD_EIM_D31__UART3_RTS */
+                                               >;
+                                       };
+                               };
+
+                               uart4 {
+                                       pinctrl_uart4_1: uart4grp-1 {
+                                               fsl,pins = <
+                                                       877  0x1b0b1    /* MX6DL_PAD_KEY_COL0__UART4_TXD */
+                                                       885  0x1b0b1    /* MX6DL_PAD_KEY_ROW0__UART4_RXD */
+                                               >;
+                                       };
+                               };
+
+                               usbotg {
+                                       pinctrl_usbotg_1: usbotggrp-1 {
+                                               fsl,pins = <
+                                                       1592 0x17059    /* MX6DL_PAD_GPIO_1__ANATOP_USBOTG_ID */
+                                               >;
+                                       };
+                               };
+
+                               usdhc1 {
+                                       pinctrl_usdhc1_1: usdhc1grp-1 {
+                                               fsl,pins = <
+                                                       1548 0x17059    /* MX6DL_PAD_SD1_CMD__USDHC1_CMD */
+                                                       1562 0x10059    /* MX6DL_PAD_SD1_CLK__USDHC1_CLK */
+                                                       1532 0x17059    /* MX6DL_PAD_SD1_DAT0__USDHC1_DAT0 */
+                                                       1524 0x17059    /* MX6DL_PAD_SD1_DAT1__USDHC1_DAT1 */
+                                                       1554 0x17059    /* MX6DL_PAD_SD1_DAT2__USDHC1_DAT2 */
+                                                       1540 0x17059    /* MX6DL_PAD_SD1_DAT3__USDHC1_DAT3 */
+                                                       1398 0x17059    /* MX6DL_PAD_NANDF_D0__USDHC1_DAT4 */
+                                                       1406 0x17059    /* MX6DL_PAD_NANDF_D1__USDHC1_DAT5 */
+                                                       1414 0x17059    /* MX6DL_PAD_NANDF_D2__USDHC1_DAT6 */
+                                                       1422 0x17059    /* MX6DL_PAD_NANDF_D3__USDHC1_DAT7 */
+                                               >;
+                                       };
+
+                                       pinctrl_usdhc1_2: usdhc1grp-2 {
+                                               fsl,pins = <
+                                                       1548 0x17059    /* MX6DL_PAD_SD1_CMD__USDHC1_CMD */
+                                                       1562 0x10059    /* MX6DL_PAD_SD1_CLK__USDHC1_CLK */
+                                                       1532 0x17059    /* MX6DL_PAD_SD1_DAT0__USDHC1_DAT0 */
+                                                       1524 0x17059    /* MX6DL_PAD_SD1_DAT1__USDHC1_DAT1 */
+                                                       1554 0x17059    /* MX6DL_PAD_SD1_DAT2__USDHC1_DAT2 */
+                                                       1540 0x17059    /* MX6DL_PAD_SD1_DAT3__USDHC1_DAT3 */
+                                               >;
+                                       };
+                               };
+
+                               usdhc2 {
+                                       pinctrl_usdhc2_1: usdhc2grp-1 {
+                                               fsl,pins = <
+                                                       1577 0x17059    /* MX6DL_PAD_SD2_CMD__USDHC2_CMD */
+                                                       1569 0x10059    /* MX6DL_PAD_SD2_CLK__USDHC2_CLK */
+                                                       16   0x17059    /* MX6DL_PAD_SD2_DAT0__USDHC2_DAT0 */
+                                                       0    0x17059    /* MX6DL_PAD_SD2_DAT1__USDHC2_DAT1 */
+                                                       8    0x17059    /* MX6DL_PAD_SD2_DAT2__USDHC2_DAT2 */
+                                                       1583 0x17059    /* MX6DL_PAD_SD2_DAT3__USDHC2_DAT3 */
+                                                       1430 0x17059    /* MX6DL_PAD_NANDF_D4__USDHC2_DAT4 */
+                                                       1438 0x17059    /* MX6DL_PAD_NANDF_D5__USDHC2_DAT5 */
+                                                       1446 0x17059    /* MX6DL_PAD_NANDF_D6__USDHC2_DAT6 */
+                                                       1454 0x17059    /* MX6DL_PAD_NANDF_D7__USDHC2_DAT7 */
+                                               >;
+                                       };
+
+                                       pinctrl_usdhc2_2: usdhc2grp-2 {
+                                               fsl,pins = <
+                                                       1577 0x17059    /* MX6DL_PAD_SD2_CMD__USDHC2_CMD */
+                                                       1569 0x10059    /* MX6DL_PAD_SD2_CLK__USDHC2_CLK */
+                                                       16   0x17059    /* MX6DL_PAD_SD2_DAT0__USDHC2_DAT0 */
+                                                       0    0x17059    /* MX6DL_PAD_SD2_DAT1__USDHC2_DAT1 */
+                                                       8    0x17059    /* MX6DL_PAD_SD2_DAT2__USDHC2_DAT2 */
+                                                       1583 0x17059    /* MX6DL_PAD_SD2_DAT3__USDHC2_DAT3 */
+                                               >;
+                                       };
+                               };
+
+                               usdhc3 {
+                                       pinctrl_usdhc3_1: usdhc3grp-1 {
+                                               fsl,pins = <
+                                                       1273 0x17059    /* MX6DL_PAD_SD3_CMD__USDHC3_CMD */
+                                                       1281 0x10059    /* MX6DL_PAD_SD3_CLK__USDHC3_CLK        */
+                                                       1289 0x17059    /* MX6DL_PAD_SD3_DAT0__USDHC3_DAT0 */
+                                                       1297 0x17059    /* MX6DL_PAD_SD3_DAT1__USDHC3_DAT1 */
+                                                       1305 0x17059    /* MX6DL_PAD_SD3_DAT2__USDHC3_DAT2 */
+                                                       1312 0x17059    /* MX6DL_PAD_SD3_DAT3__USDHC3_DAT3 */
+                                                       1265 0x17059    /* MX6DL_PAD_SD3_DAT4__USDHC3_DAT4 */
+                                                       1257 0x17059    /* MX6DL_PAD_SD3_DAT5__USDHC3_DAT5 */
+                                                       1249 0x17059    /* MX6DL_PAD_SD3_DAT6__USDHC3_DAT6 */
+                                                       1241 0x17059    /* MX6DL_PAD_SD3_DAT7__USDHC3_DAT7 */
+                                               >;
+                                       };
+
+                                       pinctrl_usdhc3_2: usdhc3grp-2 {
+                                               fsl,pins = <
+                                                       1273 0x17059    /* MX6DL_PAD_SD3_CMD__USDHC3_CMD */
+                                                       1281 0x10059    /* MX6DL_PAD_SD3_CLK__USDHC3_CLK        */
+                                                       1289 0x17059    /* MX6DL_PAD_SD3_DAT0__USDHC3_DAT0 */
+                                                       1297 0x17059    /* MX6DL_PAD_SD3_DAT1__USDHC3_DAT1 */
+                                                       1305 0x17059    /* MX6DL_PAD_SD3_DAT2__USDHC3_DAT2 */
+                                                       1312 0x17059    /* MX6DL_PAD_SD3_DAT3__USDHC3_DAT3 */
+                                               >;
+                                       };
+                               };
+
+                               usdhc4 {
+                                       pinctrl_usdhc4_1: usdhc4grp-1 {
+                                               fsl,pins = <
+                                                       1386 0x17059    /* MX6DL_PAD_SD4_CMD__USDHC4_CMD */
+                                                       1392 0x10059    /* MX6DL_PAD_SD4_CLK__USDHC4_CLK        */
+                                                       1462 0x17059    /* MX6DL_PAD_SD4_DAT0__USDHC4_DAT0 */
+                                                       1470 0x17059    /* MX6DL_PAD_SD4_DAT1__USDHC4_DAT1 */
+                                                       1478 0x17059    /* MX6DL_PAD_SD4_DAT2__USDHC4_DAT2 */
+                                                       1486 0x17059    /* MX6DL_PAD_SD4_DAT3__USDHC4_DAT3 */
+                                                       1493 0x17059    /* MX6DL_PAD_SD4_DAT4__USDHC4_DAT4 */
+                                                       1501 0x17059    /* MX6DL_PAD_SD4_DAT5__USDHC4_DAT5 */
+                                                       1509 0x17059    /* MX6DL_PAD_SD4_DAT6__USDHC4_DAT6 */
+                                                       1517 0x17059    /* MX6DL_PAD_SD4_DAT7__USDHC4_DAT7 */
+                                               >;
+                                       };
+
+                                       pinctrl_usdhc4_2: usdhc4grp-2 {
+                                               fsl,pins = <
+                                                       1386 0x17059    /* MX6DL_PAD_SD4_CMD__USDHC4_CMD */
+                                                       1392 0x10059    /* MX6DL_PAD_SD4_CLK__USDHC4_CLK        */
+                                                       1462 0x17059    /* MX6DL_PAD_SD4_DAT0__USDHC4_DAT0 */
+                                                       1470 0x17059    /* MX6DL_PAD_SD4_DAT1__USDHC4_DAT1 */
+                                                       1478 0x17059    /* MX6DL_PAD_SD4_DAT2__USDHC4_DAT2 */
+                                                       1486 0x17059    /* MX6DL_PAD_SD4_DAT3__USDHC4_DAT3 */
+                                               >;
+                                       };
+                               };
+                       };
+               };
+
+               ipu2: ipu@02800000 {
+                       #crtc-cells = <1>;
+                       compatible = "fsl,iMX6DL-ipu";
+                       reg = <0x02800000 0x400000>;
+                       interrupts = <0 8 0x4 0 7 0x4>;
+                       clocks = <&clks 133>, <&clks 134>, <&clks 137>;
+                       clock-names = "bus", "di0", "di1";
+               };
+       };
+};
diff --git a/arch/arm/dts/mx6q.dtsi b/arch/arm/dts/mx6q.dtsi
new file mode 100644 (file)
index 0000000..a1eac17
--- /dev/null
@@ -0,0 +1,428 @@
+
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/include/ "imx6qdl.dtsi"
+
+/ {
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       compatible = "arm,cortex-a9";
+                       reg = <0>;
+                       next-level-cache = <&L2>;
+                       operating-points = <
+                               /* kHz    uV */
+                               1200000 1275000
+                               996000  1250000
+                               792000  1150000
+                               396000  950000
+                       >;
+                       clock-latency = <61036>; /* two CLK32 periods */
+                       clocks = <&clks 104>, <&clks 6>, <&clks 16>,
+                                <&clks 17>, <&clks 170>;
+                       clock-names = "arm", "pll2_pfd2_396m", "step",
+                                     "pll1_sw", "pll1_sys";
+                       arm-supply = <&reg_arm>;
+                       pu-supply = <&reg_pu>;
+                       soc-supply = <&reg_soc>;
+               };
+
+               cpu@1 {
+                       compatible = "arm,cortex-a9";
+                       reg = <1>;
+                       next-level-cache = <&L2>;
+               };
+
+               cpu@2 {
+                       compatible = "arm,cortex-a9";
+                       reg = <2>;
+                       next-level-cache = <&L2>;
+               };
+
+               cpu@3 {
+                       compatible = "arm,cortex-a9";
+                       reg = <3>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       soc {
+               aips-bus@02000000 { /* AIPS1 */
+                       spba-bus@02000000 {
+                               ecspi5: ecspi@02018000 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+                                       reg = <0x02018000 0x4000>;
+                                       interrupts = <0 35 0x04>;
+                                       clocks = <&clks 116>, <&clks 116>;
+                                       clock-names = "ipg", "per";
+                                       status = "disabled";
+                               };
+                       };
+
+                       iomuxc: iomuxc@020e0000 {
+                               compatible = "fsl,imx6q-iomuxc";
+                               reg = <0x020e0000 0x4000>;
+
+                               /* shared pinctrl settings */
+                               audmux {
+                                       pinctrl_audmux_1: audmux-1 {
+                                               fsl,pins = <
+                                                       18   0x80000000 /* MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD */
+                                                       1586 0x80000000 /* MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC */
+                                                       11   0x80000000 /* MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD */
+                                                       3    0x80000000 /* MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS */
+                                               >;
+                                       };
+                               };
+
+                               ecspi1 {
+                                       pinctrl_ecspi1_1: ecspi1grp-1 {
+                                               fsl,pins = <
+                                                       101 0x100b1     /* MX6Q_PAD_EIM_D17__ECSPI1_MISO */
+                                                       109 0x100b1     /* MX6Q_PAD_EIM_D18__ECSPI1_MOSI */
+                                                       94  0x100b1     /* MX6Q_PAD_EIM_D16__ECSPI1_SCLK */
+                                               >;
+                                       };
+                               };
+
+                               enet {
+                                       pinctrl_enet_1: enetgrp-1 {
+                                               fsl,pins = <
+                                                       695 0x1b0b0     /* MX6Q_PAD_ENET_MDIO__ENET_MDIO */
+                                                       756 0x1b0b0     /* MX6Q_PAD_ENET_MDC__ENET_MDC */
+                                                       24  0x1b0b0     /* MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC */
+                                                       30  0x1b0b0     /* MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 */
+                                                       34  0x1b0b0     /* MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 */
+                                                       39  0x1b0b0     /* MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 */
+                                                       44  0x1b0b0     /* MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 */
+                                                       56  0x1b0b0     /* MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL */
+                                                       702 0x1b0b0     /* MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK */
+                                                       74  0x1b0b0     /* MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC */
+                                                       52  0x1b0b0     /* MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 */
+                                                       61  0x1b0b0     /* MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 */
+                                                       66  0x1b0b0     /* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */
+                                                       70  0x1b0b0     /* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */
+                                                       48  0x1b0b0     /* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */
+                                                       1033 0x4001b0a8 /* MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT*/
+                                               >;
+                                       };
+
+                                       pinctrl_enet_2: enetgrp-2 {
+                                               fsl,pins = <
+                                                       890 0x1b0b0     /* MX6Q_PAD_KEY_COL1__ENET_MDIO */
+                                                       909 0x1b0b0     /* MX6Q_PAD_KEY_COL2__ENET_MDC */
+                                                       24  0x1b0b0     /* MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC */
+                                                       30  0x1b0b0     /* MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0 */
+                                                       34  0x1b0b0     /* MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1 */
+                                                       39  0x1b0b0     /* MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2 */
+                                                       44  0x1b0b0     /* MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3 */
+                                                       56  0x1b0b0     /* MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL */
+                                                       702 0x1b0b0     /* MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK */
+                                                       74  0x1b0b0     /* MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC */
+                                                       52  0x1b0b0     /* MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0 */
+                                                       61  0x1b0b0     /* MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1 */
+                                                       66  0x1b0b0     /* MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2 */
+                                                       70  0x1b0b0     /* MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3 */
+                                                       48  0x1b0b0     /* MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL */
+                                               >;
+                                       };
+                               };
+
+                               gpmi-nand {
+                                       pinctrl_gpmi_nand_1: gpmi-nand-1 {
+                                               fsl,pins = <
+                                                       1328 0xb0b1     /* MX6Q_PAD_NANDF_CLE__RAWNAND_CLE */
+                                                       1336 0xb0b1     /* MX6Q_PAD_NANDF_ALE__RAWNAND_ALE */
+                                                       1344 0xb0b1     /* MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN */
+                                                       1352 0xb000     /* MX6Q_PAD_NANDF_RB0__RAWNAND_READY0 */
+                                                       1360 0xb0b1     /* MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N */
+                                                       1365 0xb0b1     /* MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N */
+                                                       1371 0xb0b1     /* MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N */
+                                                       1378 0xb0b1     /* MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N */
+                                                       1387 0xb0b1     /* MX6Q_PAD_SD4_CMD__RAWNAND_RDN */
+                                                       1393 0xb0b1     /* MX6Q_PAD_SD4_CLK__RAWNAND_WRN */
+                                                       1397 0xb0b1     /* MX6Q_PAD_NANDF_D0__RAWNAND_D0 */
+                                                       1405 0xb0b1     /* MX6Q_PAD_NANDF_D1__RAWNAND_D1 */
+                                                       1413 0xb0b1     /* MX6Q_PAD_NANDF_D2__RAWNAND_D2 */
+                                                       1421 0xb0b1     /* MX6Q_PAD_NANDF_D3__RAWNAND_D3 */
+                                                       1429 0xb0b1     /* MX6Q_PAD_NANDF_D4__RAWNAND_D4 */
+                                                       1437 0xb0b1     /* MX6Q_PAD_NANDF_D5__RAWNAND_D5 */
+                                                       1445 0xb0b1     /* MX6Q_PAD_NANDF_D6__RAWNAND_D6 */
+                                                       1453 0xb0b1     /* MX6Q_PAD_NANDF_D7__RAWNAND_D7 */
+                                                       1463 0x00b1     /* MX6Q_PAD_SD4_DAT0__RAWNAND_DQS */
+                                               >;
+                                       };
+                               };
+
+                               i2c1 {
+                                       pinctrl_i2c1_1: i2c1grp-1 {
+                                               fsl,pins = <
+                                                       137 0x4001b8b1  /* MX6Q_PAD_EIM_D21__I2C1_SCL */
+                                                       196 0x4001b8b1  /* MX6Q_PAD_EIM_D28__I2C1_SDA */
+                                               >;
+                                       };
+                               };
+
+                               uart1 {
+                                       pinctrl_uart1_1: uart1grp-1 {
+                                               fsl,pins = <
+                                                       1140 0x1b0b1    /* MX6Q_PAD_CSI0_DAT10__UART1_TXD */
+                                                       1148 0x1b0b1    /* MX6Q_PAD_CSI0_DAT11__UART1_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart1_2: uart1-grp-2 {
+                                               fsl,pins = <
+                                                       120  0x1b0b1    /* MX6Q_PAD_EIM_D19__UART1_CTS */
+                                                       128  0x1b0b1    /* MX6Q_PAD_EIM_D20__UART1_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart1_3: uart1grp-3 {
+                                               fsl,pins = <
+                                                       1242 0x1b0b1    /* MX6Q_PAD_SD3_DAT7__UART1_TXD */
+                                                       1250 0x1b0b1    /* MX6Q_PAD_SD3_DAT6__UART1_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart1_4: uart1-grp-4 {
+                                               fsl,pins = <
+                                                       1290 0x1b0b1    /* MX6Q_PAD_SD3_DAT0__UART1_CTS */
+                                                       1298 0x1b0b1    /* MX6Q_PAD_SD3_DAT1__UART1_RTS */
+                                               >;
+                                       };
+                               };
+
+                               uart2 {
+                                       pinctrl_uart2_1: uart2grp-1 {
+                                               fsl,pins = <
+                                                       183  0x1b0b1    /* MX6Q_PAD_EIM_D26__UART2_TXD */
+                                                       191  0x1b0b1    /* MX6Q_PAD_EIM_D27__UART2_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart2_2: uart2grp-2 {
+                                               fsl,pins = <
+                                                       199  0x1b0b1    /* MX6Q_PAD_EIM_D28__UART2_CTS */
+                                                       206  0x1b0b1    /* MX6Q_PAD_EIM_D29__UART2_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart2_3: uart2grp-3 {
+                                               fsl,pins = <
+                                                       1258 0x1b0b1    /* MX6Q_PAD_SD3_DAT5__UART2_TXD */
+                                                       1266 0x1b0b1    /* MX6Q_PAD_SD3_DAT6__UART2_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart2_4: uart2grp-4 {
+                                               fsl,pins = <
+                                                       1274 0x1b0b1    /* MX6Q_PAD_SD3_CMD__UART2_CTS */
+                                                       1282 0x1b0b1    /* MX6Q_PAD_SD3_CLK__UART2_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart2_5: uart2grp-5 {
+                                               fsl,pins = <
+                                                       1518 0x1b0b1    /* MX6Q_PAD_SD4_DAT7__UART2_TXD */
+                                                       1494 0x1b0b1    /* MX6Q_PAD_SD4_DAT4__UART2_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart2_6: uart2grp-6 {
+                                               fsl,pins = <
+                                                       1510 0x1b0b1    /* MX6Q_PAD_SD4_DAT6__UART2_CTS */
+                                                       1502 0x1b0b1    /* MX6Q_PAD_SD4_DAT5__UART2_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart2_7: uart2grp-7 {
+                                               fsl,pins = <
+                                                       1019 0x1b0b1    /* MX6Q_PAD_GPIO_7__UART2_TXD */
+                                                       1027 0x1b0b1    /* MX6Q_PAD_GPIO_8__UART2_RXD */
+                                               >;
+                                       };
+                               };
+
+                               uart3 {
+                                       pinctrl_uart3_1: uart3grp-1 {
+                                               fsl,pins = <
+                                                       165  0x1b0b1    /* MX6Q_PAD_EIM_D24__UART3_TXD */
+                                                       173  0x1b0b1    /* MX6Q_PAD_EIM_D25__UART3_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart3_2: uart3grp-2 {
+                                               fsl,pins = <
+                                                       149  0x1b0b1    /* MX6Q_PAD_EIM_D23__UART3_CTS */
+                                                       157  0x1b0b1    /* MX6Q_PAD_EIM_EB3__UART3_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart3_3: uart3grp-3 {
+                                               fsl,pins = <
+                                                       1388 0x1b0b1    /* MX6Q_PAD_SD4_CMD__UART3_TXD */
+                                                       1394 0x1b0b1    /* MX6Q_PAD_SD4_CLK__UART3_RXD */
+                                               >;
+                                       };
+                                       pinctrl_uart3_4: uart3grp-4 {
+                                               fsl,pins = <
+                                                       1313 0x1b0b1    /* MX6Q_PAD_SD3_DAT3__UART3_CTS */
+                                                       1321 0x1b0b1    /* MX6Q_PAD_SD3_RST__UART3_RTS */
+                                               >;
+                                       };
+
+                                       pinctrl_uart3_5: uart3grp-5 {
+                                               fsl,pins = <
+                                                       214  0x1b0b1    /* MX6Q_PAD_EIM_D30__UART3_CTS */
+                                                       222  0x1b0b1    /* MX6Q_PAD_EIM_D31__UART3_RTS */
+                                               >;
+                                       };
+                               };
+
+                               uart4 {
+                                       pinctrl_uart4_1: uart4grp-1 {
+                                               fsl,pins = <
+                                                       877  0x1b0b1    /* MX6Q_PAD_KEY_COL0__UART4_TXD */
+                                                       885  0x1b0b1    /* MX6Q_PAD_KEY_ROW0__UART4_RXD */
+                                               >;
+                                       };
+                               };
+
+                               usbotg {
+                                       pinctrl_usbotg_1: usbotggrp-1 {
+                                               fsl,pins = <
+                                                       1592 0x17059    /* MX6Q_PAD_GPIO_1__ANATOP_USBOTG_ID */
+                                               >;
+                                       };
+                               };
+
+                               usdhc1 {
+                                       pinctrl_usdhc1_1: usdhc1grp-1 {
+                                               fsl,pins = <
+                                                       1548 0x17059    /* MX6Q_PAD_SD1_CMD__USDHC1_CMD */
+                                                       1562 0x10059    /* MX6Q_PAD_SD1_CLK__USDHC1_CLK */
+                                                       1532 0x17059    /* MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 */
+                                                       1524 0x17059    /* MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 */
+                                                       1554 0x17059    /* MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 */
+                                                       1540 0x17059    /* MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 */
+                                                       1398 0x17059    /* MX6Q_PAD_NANDF_D0__USDHC1_DAT4 */
+                                                       1406 0x17059    /* MX6Q_PAD_NANDF_D1__USDHC1_DAT5 */
+                                                       1414 0x17059    /* MX6Q_PAD_NANDF_D2__USDHC1_DAT6 */
+                                                       1422 0x17059    /* MX6Q_PAD_NANDF_D3__USDHC1_DAT7 */
+                                               >;
+                                       };
+
+                                       pinctrl_usdhc1_2: usdhc1grp-2 {
+                                               fsl,pins = <
+                                                       1548 0x17059    /* MX6Q_PAD_SD1_CMD__USDHC1_CMD */
+                                                       1562 0x10059    /* MX6Q_PAD_SD1_CLK__USDHC1_CLK */
+                                                       1532 0x17059    /* MX6Q_PAD_SD1_DAT0__USDHC1_DAT0 */
+                                                       1524 0x17059    /* MX6Q_PAD_SD1_DAT1__USDHC1_DAT1 */
+                                                       1554 0x17059    /* MX6Q_PAD_SD1_DAT2__USDHC1_DAT2 */
+                                                       1540 0x17059    /* MX6Q_PAD_SD1_DAT3__USDHC1_DAT3 */
+                                               >;
+                                       };
+                               };
+
+                               usdhc2 {
+                                       pinctrl_usdhc2_1: usdhc2grp-1 {
+                                               fsl,pins = <
+                                                       1577 0x17059    /* MX6Q_PAD_SD2_CMD__USDHC2_CMD */
+                                                       1569 0x10059    /* MX6Q_PAD_SD2_CLK__USDHC2_CLK */
+                                                       16   0x17059    /* MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 */
+                                                       0    0x17059    /* MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 */
+                                                       8    0x17059    /* MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 */
+                                                       1583 0x17059    /* MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 */
+                                                       1430 0x17059    /* MX6Q_PAD_NANDF_D4__USDHC2_DAT4 */
+                                                       1438 0x17059    /* MX6Q_PAD_NANDF_D5__USDHC2_DAT5 */
+                                                       1446 0x17059    /* MX6Q_PAD_NANDF_D6__USDHC2_DAT6 */
+                                                       1454 0x17059    /* MX6Q_PAD_NANDF_D7__USDHC2_DAT7 */
+                                               >;
+                                       };
+
+                                       pinctrl_usdhc2_2: usdhc2grp-2 {
+                                               fsl,pins = <
+                                                       1577 0x17059    /* MX6Q_PAD_SD2_CMD__USDHC2_CMD */
+                                                       1569 0x10059    /* MX6Q_PAD_SD2_CLK__USDHC2_CLK */
+                                                       16   0x17059    /* MX6Q_PAD_SD2_DAT0__USDHC2_DAT0 */
+                                                       0    0x17059    /* MX6Q_PAD_SD2_DAT1__USDHC2_DAT1 */
+                                                       8    0x17059    /* MX6Q_PAD_SD2_DAT2__USDHC2_DAT2 */
+                                                       1583 0x17059    /* MX6Q_PAD_SD2_DAT3__USDHC2_DAT3 */
+                                               >;
+                                       };
+                               };
+
+                               usdhc3 {
+                                       pinctrl_usdhc3_1: usdhc3grp-1 {
+                                               fsl,pins = <
+                                                       1273 0x17059    /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */
+                                                       1281 0x10059    /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */
+                                                       1289 0x17059    /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */
+                                                       1297 0x17059    /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */
+                                                       1305 0x17059    /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */
+                                                       1312 0x17059    /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */
+                                                       1265 0x17059    /* MX6Q_PAD_SD3_DAT4__USDHC3_DAT4 */
+                                                       1257 0x17059    /* MX6Q_PAD_SD3_DAT5__USDHC3_DAT5 */
+                                                       1249 0x17059    /* MX6Q_PAD_SD3_DAT6__USDHC3_DAT6 */
+                                                       1241 0x17059    /* MX6Q_PAD_SD3_DAT7__USDHC3_DAT7 */
+                                               >;
+                                       };
+
+                                       pinctrl_usdhc3_2: usdhc3grp-2 {
+                                               fsl,pins = <
+                                                       1273 0x17059    /* MX6Q_PAD_SD3_CMD__USDHC3_CMD */
+                                                       1281 0x10059    /* MX6Q_PAD_SD3_CLK__USDHC3_CLK */
+                                                       1289 0x17059    /* MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 */
+                                                       1297 0x17059    /* MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 */
+                                                       1305 0x17059    /* MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 */
+                                                       1312 0x17059    /* MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 */
+                                               >;
+                                       };
+                               };
+
+                               usdhc4 {
+                                       pinctrl_usdhc4_1: usdhc4grp-1 {
+                                               fsl,pins = <
+                                                       1386 0x17059    /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
+                                                       1392 0x10059    /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
+                                                       1462 0x17059    /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
+                                                       1470 0x17059    /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
+                                                       1478 0x17059    /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
+                                                       1486 0x17059    /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
+                                                       1493 0x17059    /* MX6Q_PAD_SD4_DAT4__USDHC4_DAT4 */
+                                                       1501 0x17059    /* MX6Q_PAD_SD4_DAT5__USDHC4_DAT5 */
+                                                       1509 0x17059    /* MX6Q_PAD_SD4_DAT6__USDHC4_DAT6 */
+                                                       1517 0x17059    /* MX6Q_PAD_SD4_DAT7__USDHC4_DAT7 */
+                                               >;
+                                       };
+
+                                       pinctrl_usdhc4_2: usdhc4grp-2 {
+                                               fsl,pins = <
+                                                       1386 0x17059    /* MX6Q_PAD_SD4_CMD__USDHC4_CMD */
+                                                       1392 0x10059    /* MX6Q_PAD_SD4_CLK__USDHC4_CLK */
+                                                       1462 0x17059    /* MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 */
+                                                       1470 0x17059    /* MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 */
+                                                       1478 0x17059    /* MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 */
+                                                       1486 0x17059    /* MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 */
+                                               >;
+                                       };
+                               };
+                       };
+               };
+
+               ipu2: ipu@02800000 {
+                       #crtc-cells = <1>;
+                       compatible = "fsl,imx6q-ipu";
+                       reg = <0x02800000 0x400000>;
+                       interrupts = <0 8 0x4 0 7 0x4>;
+                       clocks = <&clks 133>, <&clks 134>, <&clks 137>;
+                       clock-names = "bus", "di0", "di1";
+               };
+       };
+};
index e88e6e2a9881d0dcd00af5477453afe219ed79b1..b96104c0cc9f6116aab84dd9cf35d337ac9a6fba 100644 (file)
@@ -40,6 +40,11 @@ void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
                pad_ctrl |= PAD_CTL_LVE_BIT;
        }
 #endif
+#ifdef DEBUG
+       printf("PAD[%2d]=%016llx mux[%03x]=%02x pad[%03x]=%05x%c inp[%03x]=%d\n",
+               i, pad, mux_ctrl_ofs, mux_mode, pad_ctrl_ofs, pad_ctrl,
+               pad & PAD_CTRL_VALID ? ' ' : '!', sel_input_ofs, sel_input);
+#endif
 
        if (mux_ctrl_ofs)
                __raw_writel(mux_mode, base + mux_ctrl_ofs);
@@ -48,11 +53,11 @@ void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
                __raw_writel(sel_input, base + sel_input_ofs);
 
 #ifdef CONFIG_IOMUX_SHARE_CONF_REG
-       if (!(pad_ctrl & NO_PAD_CTRL))
+       if (pad & PAD_CTRL_VALID)
                __raw_writel((mux_mode << PAD_MUX_MODE_SHIFT) | pad_ctrl,
                        base + pad_ctrl_ofs);
 #else
-       if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs)
+       if ((pad & PAD_CTRL_VALID) && pad_ctrl_ofs)
                __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
 #endif
 }
@@ -79,16 +84,11 @@ void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
 }
 
 void imx_iomux_set_gpr_register(int group, int start_bit,
-                                       int num_bits, int value)
+                               int num_bits, int value)
 {
-       int i = 0;
-       u32 reg;
-       reg = readl(base + group * 4);
-       while (num_bits) {
-               reg &= ~(1<<(start_bit + i));
-               i++;
-               num_bits--;
-       }
-       reg |= (value << start_bit);
+       u32 reg = readl(base + group * 4);
+
+       reg &= ~(((1 << num_bits) - 1) << start_bit);
+       reg |= value << start_bit;
        writel(reg, base + group * 4);
 }
index 65ef60bf2edb0a115d7bc48b1eb35dffa0b41901..1da931ab0f4a761d5e6d39eaa27910876fc7db9e 100644 (file)
@@ -75,6 +75,15 @@ static inline unsigned long long tick_to_time(unsigned long long tick)
        return tick;
 }
 
+static inline unsigned long time_to_tick(unsigned long time)
+{
+       unsigned long long ticks = (unsigned long long)time;
+
+       ticks *= MXC_CLK32;
+       do_div(ticks, CONFIG_SYS_HZ);
+       return ticks;
+}
+
 static inline unsigned long long us_to_tick(unsigned long long usec)
 {
        ulong gpt_clk = gpt_get_clk();
@@ -125,6 +134,7 @@ int timer_init(void)
        gd->arch.tbl = __raw_readl(&cur_gpt->counter);
        gd->arch.tbu = 0;
 
+       gd->arch.timer_rate_hz = MXC_CLK32;
        return 0;
 }
 
@@ -147,25 +157,36 @@ ulong get_timer_masked(void)
         * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
         * 5 * 10^6 days - long enough.
         */
+       /*
+        * LW: get_ticks() returns a long long with the top 32 bits always ZERO!
+        * Thus the calculation above is not true.
+        * A 64bit timer value would only make sense if it was
+        * consistently used throughout the code. Thus also the parameter
+        * to get_timer() and its return value would need to be 64bit wide!
+        */
        return tick_to_time(get_ticks());
 }
 
 ulong get_timer(ulong base)
 {
-       return get_timer_masked() - base;
+       return tick_to_time(get_ticks() - time_to_tick(base));
 }
 
 /* delay x useconds AND preserve advance timstamp value */
 void __udelay(unsigned long usec)
 {
-       unsigned long long tmp;
-       ulong tmo;
+       unsigned long start = __raw_readl(&cur_gpt->counter);
+       unsigned long ticks;
+
+       if (usec == 0)
+               return;
 
-       tmo = us_to_tick(usec);
-       tmp = get_ticks() + tmo;        /* get current timestamp */
+       ticks = us_to_tick(usec);
+       if (ticks == 0)
+               ticks++;
 
-       while (get_ticks() < tmp)       /* loop till event */
-                /*NOP*/;
+       while (__raw_readl(&cur_gpt->counter) - start < ticks)
+               /* loop till event */;
 }
 
 /*
index 4c9352a2ed768f29bcec1ff5678807ccbb396464..5657f1846a30614fef2343d20fb608010e4ce751 100644 (file)
 #define CONFIG_SYS_MPUCLK      MPUPLL_M_550
 #endif
 
+#define DISPPLL_M      200
+#define DISPPLL_N      (OSC - 1)
+#define DISPPLL_M2     1
+
 #define UART_RESET             (0x1 << 1)
 #define UART_CLK_RUNNING_MASK  0x1
 #define UART_SMART_IDLE_EN     (0x1 << 0x3)
index b94b56cba73d3d8ef5f569eb9c126f40d2033fdc..3f1da852e55c687e55b2d352e8963e1a3956b49c 100644 (file)
 
 #include <asm/arch/hardware.h>
 
-#define BIT(x)                         (1 << x)
-#define CL_BIT(x)                      (0 << x)
+#define BIT(x)                         (1 << (x))
+#define CL_BIT(x)                      (0 << (x))
 
 /* Timer register bits */
 #define TCLR_ST                                BIT(0)  /* Start=1 Stop=0 */
 #define TCLR_AR                                BIT(1)  /* Auto reload */
 #define TCLR_PRE                       BIT(5)  /* Pre-scaler enable */
-#define TCLR_PTV_SHIFT                 (2)     /* Pre-scaler shift value */
+#define TCLR_PTV_SHIFT                 2       /* Pre-scaler shift value */
 #define TCLR_PRE_DISABLE               CL_BIT(5) /* Pre-scalar disable */
 #define TCLR_CE                                BIT(6)  /* compare mode enable */
 #define TCLR_SCPWM                     BIT(7)  /* pwm outpin behaviour */
@@ -60,8 +60,8 @@
 #define AM335X_ZCE_600                 0x1F9F
 
 /* This gives the status of the boot mode pins on the evm */
-#define SYSBOOT_MASK                   (BIT(0) | BIT(1) | BIT(2)\
-                                       | BIT(3) | BIT(4))
+#define SYSBOOT_MASK                   (BIT(0) | BIT(1) | BIT(2) | \
+                                               BIT(3) | BIT(4))
 
 #define PRM_RSTCTRL_RESET              0x01
 #define PRM_RSTST_WARM_RESET_MASK      0x232
@@ -106,7 +106,9 @@ struct cm_wkuppll {
        unsigned int idlestdpllddr;     /* offset 0x34 */
        unsigned int resv5[2];
        unsigned int clkseldpllddr;     /* offset 0x40 */
-       unsigned int resv6[4];
+       unsigned int autoidledplldisp;  /* offset 0x44 */
+       unsigned int idlestdplldisp;    /* offset 0x48 */
+       unsigned int resv6[2];
        unsigned int clkseldplldisp;    /* offset 0x54 */
        unsigned int resv7[1];
        unsigned int idlestdpllcore;    /* offset 0x5c */
@@ -150,7 +152,7 @@ struct cm_perpll {
        unsigned int resv1;
        unsigned int cpgmac0clkctrl;    /* offset 0x14 */
        unsigned int lcdclkctrl;        /* offset 0x18 */
-       unsigned int usb0clkctrl;       /* offset 0x1C */
+       unsigned int usb0clkctrl;       /* offset 0x1c */
        unsigned int resv2;
        unsigned int tptc0clkctrl;      /* offset 0x24 */
        unsigned int emifclkctrl;       /* offset 0x28 */
@@ -454,7 +456,7 @@ struct gptimer {
        unsigned int twpc;              /* offset 0x48 */
        unsigned int tmar;              /* offset 0x4c */
        unsigned int tcar1;             /* offset 0x50 */
-       unsigned int tscir;             /* offset 0x54 */
+       unsigned int tsicr;             /* offset 0x54 */
        unsigned int tcar2;             /* offset 0x58 */
 };
 
@@ -475,7 +477,7 @@ struct ctrl_stat {
        unsigned int resv1[16];
        unsigned int statusreg;         /* ofset 0x40 */
        unsigned int resv2[51];
-       unsigned int secure_emif_sdram_config;  /* offset 0x0110 */
+       unsigned int emif_sdram_config; /* offset 0x0110 */
        unsigned int resv3[319];
        unsigned int dev_attr;
 };
@@ -585,7 +587,22 @@ struct pwmss_ecap_regs {
 #define ECTRL2_PLSL_LOW                BIT(10)
 #define ECTRL2_SYNC_EN         BIT(5)
 
+#define clk_get_rate(c,p)                                      \
+       __clk_get_rate(readl(&(c)->clkseldpll##p),              \
+               readl(&(c)->divm2dpll##p))
+
+unsigned long __clk_get_rate(u32 m_n, u32 div_m2);
+
+unsigned long mpu_clk_rate(void);
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL_STRICT_NAMES */
 
+/* Ethernet MAC ID from EFuse */
+#define MAC_ID0_LO     (CTRL_BASE + 0x630)
+#define MAC_ID0_HI     (CTRL_BASE + 0x634)
+#define MAC_ID1_LO     (CTRL_BASE + 0x638)
+#define MAC_ID1_HI     (CTRL_BASE + 0x63c)
+#define MAC_MII_SEL    (CTRL_BASE + 0x650)
+
 #endif /* _AM33XX_CPU_H */
diff --git a/arch/arm/include/asm/arch-am33xx/da8xx-fb.h b/arch/arm/include/asm/arch-am33xx/da8xx-fb.h
new file mode 100644 (file)
index 0000000..208b232
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * Porting to u-boot:
+ *
+ * (C) Copyright 2011
+ * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
+ *
+ * Copyright (C) 2008-2009 MontaVista Software Inc.
+ * Copyright (C) 2008-2009 Texas Instruments Inc
+ *
+ * Based on the LCD driver for TI Avalanche processors written by
+ * Ajay Singh and Shalom Hai.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option)any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef DA8XX_FB_H
+#define DA8XX_FB_H
+
+enum panel_type {
+       QVGA = 0
+};
+
+enum panel_shade {
+       MONOCHROME = 0,
+       COLOR_ACTIVE,
+       COLOR_PASSIVE,
+};
+
+enum raster_load_mode {
+       LOAD_DATA = 1,
+       LOAD_PALETTE,
+};
+
+struct display_panel {
+       enum panel_type panel_type; /* QVGA */
+       int max_bpp;
+       int min_bpp;
+       enum panel_shade panel_shade;
+};
+
+struct da8xx_panel {
+       const char      name[25];       /* Full name <vendor>_<model> */
+       unsigned short  width;
+       unsigned short  height;
+       int             hfp;            /* Horizontal front porch */
+       int             hbp;            /* Horizontal back porch */
+       int             hsw;            /* Horizontal Sync Pulse Width */
+       int             vfp;            /* Vertical front porch */
+       int             vbp;            /* Vertical back porch */
+       int             vsw;            /* Vertical Sync Pulse Width */
+       unsigned int    pxl_clk;        /* Pixel clock */
+       unsigned char   invert_pxl_clk; /* Invert Pixel clock */
+};
+
+struct da8xx_lcdc_platform_data {
+       const char manu_name[10];
+       void *controller_data;
+       const char type[25];
+       void (*panel_power_ctrl)(int);
+};
+
+struct lcd_ctrl_config {
+       const struct display_panel *p_disp_panel;
+
+       /* AC Bias Pin Frequency */
+       int ac_bias;
+
+       /* AC Bias Pin Transitions per Interrupt */
+       int ac_bias_intrpt;
+
+       /* DMA burst size */
+       int dma_burst_sz;
+
+       /* Bits per pixel */
+       int bpp;
+
+       /* FIFO DMA Request Delay */
+       int fdd;
+
+       /* TFT Alternative Signal Mapping (Only for active) */
+       unsigned char tft_alt_mode;
+
+       /* 12 Bit Per Pixel (5-6-5) Mode (Only for passive) */
+       unsigned char stn_565_mode;
+
+       /* Mono 8-bit Mode: 1=D0-D7 or 0=D0-D3 */
+       unsigned char mono_8bit_mode;
+
+       /* Invert line clock */
+       unsigned char invert_line_clock;
+
+       /* Invert frame clock  */
+       unsigned char invert_frm_clock;
+
+       /* Horizontal and Vertical Sync Edge: 0=rising 1=falling */
+       unsigned char sync_edge;
+
+       /* Horizontal and Vertical Sync: Control: 0=ignore */
+       unsigned char sync_ctrl;
+
+       /* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */
+       unsigned char raster_order;
+};
+
+struct lcd_sync_arg {
+       int back_porch;
+       int front_porch;
+       int pulse_width;
+};
+
+void da8xx_fb_disable(void);
+void da8xx_video_init(const struct da8xx_panel *panel, int bits_pixel);
+
+#endif  /* ifndef DA8XX_FB_H */
index 97bbfe2e65e887991899889df3fb23e55052a43e..719f3e22905c2bdf86b2f3e77f97c8ef43d80934 100644 (file)
 /* AM335X EMIF Register values */
 #define VTP_CTRL_READY         (0x1 << 5)
 #define VTP_CTRL_ENABLE                (0x1 << 6)
-#define VTP_CTRL_START_EN      (0x1)
+#define VTP_CTRL_FILTER_SHIFT  1
+#define VTP_CTRL_FILTER_MASK   (0x7 << VTP_CTRL_FILTER_SHIFT)
+#define VTP_CTRL_FILTER(n)     (((n) << VTP_CTRL_FILTER_SHIFT) & VTP_CTRL_FILTER_MASK)
+#define VTP_CTRL_START_EN      (0x1 << 0)
+#define PHY_DLL_LOCK_DIFF      0x0
 #ifdef CONFIG_AM43XX
 #define DDR_CKE_CTRL_NORMAL    0x3
 #else
index 220603db5a3858a7764e2233a5a0ef990be52eef..3f6365e9e8f1bb8dfc2ad681c283a2f20b66b298 100644 (file)
@@ -15,6 +15,8 @@
 #define AM33XX_GPIO4_BASE      0x48320000
 #define AM33XX_GPIO5_BASE      0x48322000
 
+#define AM33XX_GPIO_NR(bank, pin)      (((bank) << 5) | (pin))
+
 /* GPIO CTRL register */
 #define GPIO_CTRL_DISABLEMODULE_SHIFT  0
 #define GPIO_CTRL_DISABLEMODULE_MASK   (1 << 0)
index 724e252946d4daa7b23f5ac0e140797c011f9d09..4274eba6d28c659c5ec8a20c62c971e4a41b4220 100644 (file)
@@ -23,6 +23,7 @@
  */
 #define OMAP_HSMMC1_BASE               0x48060100
 #define OMAP_HSMMC2_BASE               0x481D8100
+#define OMAP_HSMMC3_BASE               0x47810100
 
 #if defined(CONFIG_TI814X)
 #undef MMC_CLOCK_REFERENCE
index 4968d3dd2e6cd732f4f49482a78464bea8c0d50f..518cc8182b4f889868f1ca673c4ae12ad60f6855 100644 (file)
@@ -10,7 +10,7 @@
 
 #ifndef __ASSEMBLY__
 struct exynos4_sysreg {
-       unsigned char   res1[0x210];
+       unsigned int    res1[0x210 / 4];
        unsigned int    display_ctrl;
        unsigned int    display_ctrl2;
        unsigned int    camera_control;
@@ -19,7 +19,7 @@ struct exynos4_sysreg {
 };
 
 struct exynos5_sysreg {
-       unsigned char   res1[0x214];
+       unsigned int    res1[0x214 / 4];
        unsigned int    disp1blk_cfg;
        unsigned int    disp2blk_cfg;
        unsigned int    hdcp_e_fuse;
@@ -28,7 +28,7 @@ struct exynos5_sysreg {
        unsigned int    reserved;
        unsigned int    ispblk_cfg;
        unsigned int    usb20phy_cfg;
-       unsigned char   res2[0x29c];
+       unsigned int    res2[0x29c / 4];
        unsigned int    mipi_dphy;
        unsigned int    dptx_dphy;
        unsigned int    phyclk_sel;
index 3db4112d1f4abfae6ec4cbdb53a6bfc01a310d42..f4582ee833a82b4884eaba639f171e8a7975bd6c 100644 (file)
@@ -39,12 +39,63 @@ enum mxc_clock {
        MXC_NFC_CLK,
        MXC_PERIPH_CLK,
        MXC_I2C_CLK,
+       MXC_AXI_A_CLK,
+       MXC_AXI_B_CLK,
+       MXC_EMI_SLOW_CLK,
+};
+
+
+struct clk {
+       const char *name;
+       int id;
+       /* Source clock this clk depends on */
+       struct clk *parent;
+       /* Secondary clock to enable/disable with this clock */
+       struct clk *secondary;
+       /* Current clock rate */
+       unsigned long rate;
+       /* Reference count of clock enable/disable */
+       __s8 usecount;
+       /* Register bit position for clock's enable/disable control. */
+       u8 enable_shift;
+       /* Register address for clock's enable/disable control. */
+       void *enable_reg;
+       u32 flags;
+       /*
+        * Function ptr to recalculate the clock's rate based on parent
+        * clock's rate
+        */
+       void (*recalc) (struct clk *);
+       /*
+        * Function ptr to set the clock to a new rate. The rate must match a
+        * supported rate returned from round_rate. Leave blank if clock is not
+       * programmable
+        */
+       int (*set_rate) (struct clk *, unsigned long);
+       /*
+        * Function ptr to round the requested clock rate to the nearest
+        * supported rate that is less than or equal to the requested rate.
+        */
+       unsigned long (*round_rate) (struct clk *, unsigned long);
+       /*
+        * Function ptr to enable the clock. Leave blank if clock can not
+        * be gated.
+        */
+       int (*enable) (struct clk *);
+       /*
+        * Function ptr to disable the clock. Leave blank if clock can not
+        * be gated.
+        */
+       void (*disable) (struct clk *);
+       /* Function ptr to set the parent clock of the clock. */
+       int (*set_parent) (struct clk *, struct clk *);
 };
 
 u32 imx_get_uartclk(void);
 u32 imx_get_fecclk(void);
 unsigned int mxc_get_clock(enum mxc_clock clk);
-int mxc_set_clock(u32 ref, u32 freq, u32 clk_type);
+int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk);
+int adjust_core_voltage(u32 freq);
 void set_usb_phy_clk(void);
 void enable_usb_phy1_clk(bool enable);
 void enable_usb_phy2_clk(bool enable);
@@ -54,5 +105,20 @@ void mxc_set_sata_internal_clock(void);
 int enable_i2c_clk(unsigned char enable, unsigned i2c_num);
 void enable_nfc_clk(unsigned char enable);
 void enable_efuse_prog_supply(bool enable);
+void ipu_clk_enable(void);
+void ipu_clk_disable(void);
+void ipu_di_clk_enable(int di);
+void ipu_di_clk_disable(int di);
+#ifdef CONFIG_MX53
+void ldb_clk_enable(int ldb);
+void ldb_clk_disable(int ldb);
+#else
+static inline void ldb_clk_enable(int ldb)
+{
+}
+static inline void ldb_clk_disable(int ldb)
+{
+}
+#endif /* CONFIG_MX53 */
 
 #endif /* __ASM_ARCH_CLOCK_H */
index b61c7b970a6bff4b801a39d449da45c268d17345..fee81e490089fda5d9770d5f5dbb798bf144a62c 100644 (file)
@@ -303,7 +303,7 @@ struct mxc_ccm_reg {
 #define MXC_CCM_CSCDR1_UART_CLK_PODF_RD(r)             ((r) & 0x7)
 
 /* Define the bits in register CCDR */
-#define MXC_CCM_CCDR_IPU_HS_MASK                       (0x1 << 17)
+#define MXC_CCM_CCDR_IPU_HS_MASK                       (0x1 << 21)
 
 /* Define the bits in register CGPR */
 #define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE            (1 << 4)
@@ -591,7 +591,7 @@ struct mxc_ccm_reg {
 #endif
 
 /* Define the bits in register CLPCR */
-#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS                 (0x1 << 18)
+#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS                        (0x1 << 18)
 
 #define        MXC_DPLLC_CTL_HFSM                              (1 << 7)
 #define        MXC_DPLLC_CTL_DPDCK0_2_EN                       (1 << 12)
index f059d0f664b35b4f5630347cdffeb60c56194efb..091055f8f07fb723f9fbb07a3acc802bcd008059 100644 (file)
 #if defined(CONFIG_MX51)
 #define IRAM_BASE_ADDR         0x1FFE0000      /* internal ram */
 #define IPU_SOC_BASE_ADDR      0x40000000
-#define IPU_SOC_OFFSET         0x1E000000
-#define SPBA0_BASE_ADDR         0x70000000
-#define AIPS1_BASE_ADDR         0x73F00000
-#define AIPS2_BASE_ADDR         0x83F00000
-#define CSD0_BASE_ADDR          0x90000000
-#define CSD1_BASE_ADDR          0xA0000000
-#define NFC_BASE_ADDR_AXI       0xCFFF0000
-#define CS1_BASE_ADDR           0xB8000000
+#define SPBA0_BASE_ADDR                0x70000000
+#define AIPS1_BASE_ADDR                0x73F00000
+#define AIPS2_BASE_ADDR                0x83F00000
+#define CSD0_BASE_ADDR         0x90000000
+#define CSD1_BASE_ADDR         0xA0000000
+#define NFC_BASE_ADDR_AXI      0xCFFF0000
+#define CS1_BASE_ADDR          0xB8000000
 #elif defined(CONFIG_MX53)
-#define IPU_SOC_BASE_ADDR      0x18000000
-#define IPU_SOC_OFFSET         0x06000000
-#define SPBA0_BASE_ADDR         0x50000000
-#define AIPS1_BASE_ADDR         0x53F00000
-#define AIPS2_BASE_ADDR         0x63F00000
-#define CSD0_BASE_ADDR          0x70000000
-#define CSD1_BASE_ADDR          0xB0000000
-#define NFC_BASE_ADDR_AXI       0xF7FF0000
-#define IRAM_BASE_ADDR          0xF8000000
-#define CS1_BASE_ADDR           0xF4000000
+#define IPU_SOC_BASE_ADDR      0x00000000
+#define SPBA0_BASE_ADDR                0x50000000
+#define AIPS1_BASE_ADDR                0x53F00000
+#define AIPS2_BASE_ADDR                0x63F00000
+#define CSD0_BASE_ADDR         0x70000000
+#define CSD1_BASE_ADDR         0xB0000000
+#define NFC_BASE_ADDR_AXI      0xF7FF0000
+#define IRAM_BASE_ADDR         0xF8000000
+#define CS1_BASE_ADDR          0xF4000000
 #define SATA_BASE_ADDR         0x10000000
 #else
 #error "CPU_TYPE not defined"
@@ -44,7 +42,7 @@
 #define MMC_SDHC1_BASE_ADDR    (SPBA0_BASE_ADDR + 0x00004000)
 #define MMC_SDHC2_BASE_ADDR    (SPBA0_BASE_ADDR + 0x00008000)
 #define UART3_BASE             (SPBA0_BASE_ADDR + 0x0000C000)
-#define CSPI1_BASE_ADDR        (SPBA0_BASE_ADDR + 0x00010000)
+#define CSPI1_BASE_ADDR                (SPBA0_BASE_ADDR + 0x00010000)
 #define SSI2_BASE_ADDR         (SPBA0_BASE_ADDR + 0x00014000)
 #define MMC_SDHC3_BASE_ADDR    (SPBA0_BASE_ADDR + 0x00020000)
 #define MMC_SDHC4_BASE_ADDR    (SPBA0_BASE_ADDR + 0x00024000)
 #define GPC_BASE_ADDR          (AIPS1_BASE_ADDR + 0x000D8000)
 
 #if defined(CONFIG_MX53)
-#define GPIO5_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000DC000)
-#define GPIO6_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000E0000)
-#define GPIO7_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000E4000)
+#define GPIO5_BASE_ADDR                (AIPS1_BASE_ADDR + 0x000DC000)
+#define GPIO6_BASE_ADDR                (AIPS1_BASE_ADDR + 0x000E0000)
+#define GPIO7_BASE_ADDR                (AIPS1_BASE_ADDR + 0x000E4000)
 #define I2C3_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000EC000)
-#define UART4_BASE_ADDR         (AIPS1_BASE_ADDR + 0x000F0000)
+#define UART4_BASE_ADDR                (AIPS1_BASE_ADDR + 0x000F0000)
 #endif
 /*
  * AIPS 2
@@ -98,7 +96,7 @@
 #define IIM_BASE_ADDR          (AIPS2_BASE_ADDR + 0x00098000)
 #define CSU_BASE_ADDR          (AIPS2_BASE_ADDR + 0x0009C000)
 #define ARM_BASE_ADDR          (AIPS2_BASE_ADDR + 0x000A0000)
-#define OWIRE_BASE_ADDR        (AIPS2_BASE_ADDR + 0x000A4000)
+#define OWIRE_BASE_ADDR                (AIPS2_BASE_ADDR + 0x000A4000)
 #define FIRI_BASE_ADDR         (AIPS2_BASE_ADDR + 0x000A8000)
 #define CSPI2_BASE_ADDR                (AIPS2_BASE_ADDR + 0x000AC000)
 #define SDMA_BASE_ADDR         (AIPS2_BASE_ADDR + 0x000B0000)
 #define SAHARA_BASE_ADDR       (AIPS2_BASE_ADDR + 0x000F8000)
 
 #if defined(CONFIG_MX53)
-#define UART5_BASE_ADDR         (AIPS2_BASE_ADDR + 0x00090000)
+#define UART5_BASE_ADDR                (AIPS2_BASE_ADDR + 0x00090000)
 #endif
 
 /*
 /*
  * Number of GPIO pins per port
  */
-#define GPIO_NUM_PIN            32
+#define GPIO_NUM_PIN   32
 
 #define IIM_SREV       0x24
 #define ROM_SI_REV     0x48
 #define DP_MFD_665     (96 - 1)
 #define DP_MFN_665     89
 
+#define DP_OP_600       ((6 << 4) + ((1 - 1)  << 0))
+#define DP_MFD_600      (4 - 1)
+#define DP_MFN_600      1
+
 #define DP_OP_532      ((5 << 4) + ((1 - 1)  << 0))
 #define DP_MFD_532     (24 - 1)
 #define DP_MFN_532     13
 
-#define DP_OP_400      ((8 << 4) + ((2 - 1)  << 0))
-#define DP_MFD_400     (3 - 1)
-#define DP_MFN_400     1
+#define DP_OP_533      ((5 << 4) + ((1 - 1)  << 0))
+#define DP_MFD_533     (9 - 1)
+#define DP_MFN_533     5
 
 #define DP_OP_455      ((9 << 4) + ((2 - 1)  << 0))
 #define DP_MFD_455     (48 - 1)
 #define DP_MFN_455     23
 
+#define DP_OP_400      ((8 << 4) + ((2 - 1)  << 0))
+#define DP_MFD_400     (3 - 1)
+#define DP_MFN_400     1
+
+#define DP_OP_333      ((6 << 4) + ((2 - 1)  << 0))
+#define DP_MFD_333     (16 - 1)
+#define DP_MFN_333     15
+
 #define DP_OP_216      ((6 << 4) + ((3 - 1)  << 0))
 #define DP_MFD_216     (4 - 1)
 #define DP_MFN_216     3
 
-#define CHIP_REV_1_0            0x10
-#define CHIP_REV_1_1            0x11
-#define CHIP_REV_2_0            0x20
-#define CHIP_REV_2_5           0x25
-#define CHIP_REV_3_0            0x30
+#define CHIP_REV_1_0   0x10
+#define CHIP_REV_1_1   0x11
+#define CHIP_REV_2_0   0x20
+#define CHIP_REV_2_5   0x25
+#define CHIP_REV_3_0   0x30
 
-#define BOARD_REV_1_0           0x0
-#define BOARD_REV_2_0           0x1
+#define BOARD_REV_1_0  0x0
+#define BOARD_REV_2_0  0x1
 
 #define BOARD_VER_OFFSET       0x8
 
-#define IMX_IIM_BASE            (IIM_BASE_ADDR)
+#define IMX_IIM_BASE   IIM_BASE_ADDR
 
 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
 #include <asm/types.h>
@@ -470,7 +480,7 @@ struct cspi_regs {
 struct iim_regs {
        u32     stat;
        u32     statm;
-       u32     err;
+       u32     err;
        u32     emask;
        u32     fctl;
        u32     ua;
@@ -478,7 +488,7 @@ struct iim_regs {
        u32     sdat;
        u32     prev;
        u32     srev;
-       u32     prg_p;
+       u32     preg_p;
        u32     scs0;
        u32     scs1;
        u32     scs2;
index 70aaa37f9d5c5f72078e54097ef9c4457ed0b121..532ae4d62c1406ba51cdb171b9ca9133f300610a 100644 (file)
 #include <asm/imx-common/iomux-v3.h>
 
 /* Pad control groupings */
-#define MX51_UART_PAD_CTRL     (PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_HIGH | \
+#define MX51_UART_PAD_CTRL     MUX_PAD_CTRL(PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_HIGH | \
                                PAD_CTL_HYS | PAD_CTL_SRE_FAST)
-#define MX51_I2C_PAD_CTRL      (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
+#define MX51_I2C_PAD_CTRL      MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
                                PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | \
                                PAD_CTL_HYS)
-#define MX51_ESDHC_PAD_CTRL    (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
+#define MX51_ESDHC_PAD_CTRL    MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
                                PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | \
                                PAD_CTL_HYS)
-#define MX51_USBH_PAD_CTRL     (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
+#define MX51_USBH_PAD_CTRL     MUX_PAD_CTRL(PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
                                PAD_CTL_PUS_100K_UP | PAD_CTL_HYS)
-#define MX51_ECSPI_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_HYS | \
+#define MX51_ECSPI_PAD_CTRL    MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_HYS | \
                                PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST)
-#define MX51_SDHCI_PAD_CTRL    (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \
+#define MX51_SDHCI_PAD_CTRL    MUX_PAD_CTRL(PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \
                                PAD_CTL_SRE_FAST | PAD_CTL_DVS)
-#define MX51_GPIO_PAD_CTRL     (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | PAD_CTL_SRE_FAST)
+#define MX51_GPIO_PAD_CTRL     MUX_PAD_CTRL(PAD_CTL_DSE_HIGH | PAD_CTL_PKE | PAD_CTL_SRE_FAST)
 
-#define MX51_PAD_CTRL_2                (PAD_CTL_PKE | PAD_CTL_HYS)
-#define MX51_PAD_CTRL_4                (PAD_CTL_PKE | PAD_CTL_DVS | PAD_CTL_HYS)
-#define MX51_PAD_CTRL_5                (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+#define MX51_PAD_CTRL_2                MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_4                MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_DVS | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_5                MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+
+#define MX51_PAD_CTRL_2                MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_3                MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
+#define MX51_PAD_CTRL_4                MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_DVS | PAD_CTL_HYS)
+#define MX51_PAD_CTRL_5                MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
 
 /*
  * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
@@ -66,6 +71,9 @@ enum {
        MX51_PAD_EIM_A16__GPIO2_10              = IOMUX_PAD(0x430, 0x09c, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_EIM_A17__GPIO2_11              = IOMUX_PAD(0x434, 0x0a0, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_EIM_A20__GPIO2_14              = IOMUX_PAD(0x440, 0x0ac, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_EIM_A21__BOOT_UART_SRC1        = IOMUX_PAD(0x444, 0x0b0, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_EIM_A21__EIM_A21               = IOMUX_PAD(0x444, 0x0b0, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_EIM_A21__GPIO2_15              = IOMUX_PAD(0x444, 0x0b0, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_EIM_A22__GPIO2_16              = IOMUX_PAD(0x448, 0x0b4, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_EIM_A24__USBH2_CLK             = IOMUX_PAD(0x450, 0x0bc, 2, __NA_, 0, MX51_USBH_PAD_CTRL),
        MX51_PAD_EIM_A25__USBH2_DIR             = IOMUX_PAD(0x454, 0x0c0, 2, __NA_, 0, MX51_USBH_PAD_CTRL),
@@ -82,6 +90,12 @@ enum {
        MX51_PAD_EIM_CS3__GPIO2_28              = IOMUX_PAD(0x480, 0x0ec, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_EIM_CS4__FEC_RX_ER             = IOMUX_PAD(0x484, 0x0f0, 3, 0x970, 0, MX51_PAD_CTRL_2),
        MX51_PAD_EIM_CS4__GPIO2_29              = IOMUX_PAD(0x484, 0x0f0, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_EIM_CS5__AUD5_TXFS             = IOMUX_PAD(0x488, 0x0f4, 6, 0x8e8, 1, NO_PAD_CTRL),
+       MX51_PAD_EIM_CS5__CSI1_D7               = IOMUX_PAD(0x488, 0x0f4, 5, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_EIM_CS5__DISP1_EXT_CLK         = IOMUX_PAD(0x488, 0x0f4, 4, 0x904, 0, NO_PAD_CTRL),
+       MX51_PAD_EIM_CS5__EIM_CS5               = IOMUX_PAD(0x488, 0x0f4, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_EIM_CS5__GPIO2_30              = IOMUX_PAD(0x488, 0x0f4, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_EIM_CS5__USBOTG_DIR            = IOMUX_PAD(0x488, 0x0f4, 2, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_EIM_CS5__FEC_CRS               = IOMUX_PAD(0x488, 0x0f4, 3, 0x950, 0, MX51_PAD_CTRL_2),
        MX51_PAD_DRAM_RAS__DRAM_RAS             = IOMUX_PAD(0x4a4, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_DRAM_CAS__DRAM_CAS             = IOMUX_PAD(0x4a8, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
@@ -111,8 +125,13 @@ enum {
        MX51_PAD_NANDF_RB3__FEC_RX_CLK          = IOMUX_PAD(0x504, 0x128, 1, 0x968, 0, MX51_PAD_CTRL_2),
        MX51_PAD_NANDF_RB3__GPIO3_11            = IOMUX_PAD(0x504, 0x128, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_GPIO_NAND__PATA_INTRQ          = IOMUX_PAD(0x514, 0x12c, 1, __NA_, 0, NO_PAD_CTRL),
-       MX51_PAD_NANDF_CS2__FEC_TX_ER           = IOMUX_PAD(0x520, 0x138, 2, __NA_, 0, MX51_PAD_CTRL_5),
+       MX51_PAD_NANDF_CS2__NANDF_CS2           = IOMUX_PAD(0x520, 0x138, 0, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_NANDF_CS2__PATA_CS_0           = IOMUX_PAD(0x520, 0x138, 1, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_NANDF_CS2__FEC_TX_ER           = IOMUX_PAD(0x520, 0x138, 2, __NA_, 0, MX51_PAD_CTRL_5),
+       MX51_PAD_NANDF_CS2__GPIO3_18            = IOMUX_PAD(0x520, 0x138, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_NANDF_CS2__SD4_CLK             = IOMUX_PAD(0x520, 0x138, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS),
+       MX51_PAD_NANDF_CS2__CSPI_SCLK           = IOMUX_PAD(0x520, 0x138, 6, 0x914, 0, MX51_ECSPI_PAD_CTRL),
+       MX51_PAD_NANDF_CS2__USBH3_H1_DP         = IOMUX_PAD(0x520, 0x138, 7, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_NANDF_CS3__FEC_MDC             = IOMUX_PAD(0x524, 0x13c, 2, __NA_, 0, MX51_PAD_CTRL_5),
        MX51_PAD_NANDF_CS3__PATA_CS_1           = IOMUX_PAD(0x524, 0x13c, 1, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_NANDF_CS4__FEC_TDATA1          = IOMUX_PAD(0x528, 0x140, 2, __NA_, 0, MX51_PAD_CTRL_5),
@@ -149,6 +168,14 @@ enum {
        MX51_PAD_NANDF_D0__PATA_DATA0           = IOMUX_PAD(0x578, 0x190, 1, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_CSI2_D12__GPIO4_9              = IOMUX_PAD(0x5bc, 0x1cc, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_CSI2_D13__GPIO4_10             = IOMUX_PAD(0x5c0, 0x1d0, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_CSI2_VSYNC__CSI2_VSYNC         = IOMUX_PAD(0x5dc, 0x1ec, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_CSI2_VSYNC__GPIO4_13           = IOMUX_PAD(0x5dc, 0x1ec, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_CSI2_HSYNC__CSI2_HSYNC         = IOMUX_PAD(0x5e0, 0x1f0, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_CSI2_HSYNC__GPIO4_14           = IOMUX_PAD(0x5e0, 0x1f0, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_I2C1_CLK__GPIO4_16             = IOMUX_PAD(0x5e8, 0x1f8, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_I2C1_CLK__I2C1_CLK             = IOMUX_PAD(0x5e8, 0x1f8, 0x10, __NA_, 0, MX51_I2C_PAD_CTRL),
+       MX51_PAD_I2C1_DAT__GPIO4_17             = IOMUX_PAD(0x5ec, 0x1fc, 3, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_I2C1_DAT__I2C1_DAT             = IOMUX_PAD(0x5ec, 0x1fc, 0x10, __NA_, 0, MX51_I2C_PAD_CTRL),
        MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI        = IOMUX_PAD(0x600, 0x210, 0, __NA_, 0, MX51_ECSPI_PAD_CTRL),
        MX51_PAD_CSPI1_MISO__ECSPI1_MISO        = IOMUX_PAD(0x604, 0x214, 0, __NA_, 0, MX51_ECSPI_PAD_CTRL),
        MX51_PAD_CSPI1_SS0__ECSPI1_SS0          = IOMUX_PAD(0x608, 0x218, 0, __NA_, 0, MX51_ECSPI_PAD_CTRL),
@@ -182,6 +209,65 @@ enum {
        MX51_PAD_DI1_D1_CS__GPIO3_4             = IOMUX_PAD(0x6b8, 0x2b8, 4, 0x984, 1, MX51_GPIO_PAD_CTRL),
        MX51_PAD_DISPB2_SER_DIN__GPIO3_5        = IOMUX_PAD(0x6bc, 0x2bc, 4, 0x988, 1, MX51_GPIO_PAD_CTRL),
        MX51_PAD_DISPB2_SER_DIO__GPIO3_6        = IOMUX_PAD(0x6c0, 0x2c0, 4, 0x98c, 1, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS   = IOMUX_PAD(0x6c8, 0x2c8, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISPB2_SER_RS__DISP1_PIN16     = IOMUX_PAD(0x6c8, 0x2c8, 2, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISPB2_SER_RS__DISP1_PIN8      = IOMUX_PAD(0x6c8, 0x2c8, 3, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISPB2_SER_RS__GPIO3_8         = IOMUX_PAD(0x6c8, 0x2c8, 4, 0x994, 1, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT0__DISP1_DAT0         = IOMUX_PAD(0x6cc, 0x2cc, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT1__DISP1_DAT1         = IOMUX_PAD(0x6d0, 0x2d0, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT2__DISP1_DAT2         = IOMUX_PAD(0x6d4, 0x2d4, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT3__DISP1_DAT3         = IOMUX_PAD(0x6d8, 0x2d8, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT4__DISP1_DAT4         = IOMUX_PAD(0x6dc, 0x2dc, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT5__DISP1_DAT5         = IOMUX_PAD(0x6e0, 0x2e0, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT6__BOOT_USB_SRC       = IOMUX_PAD(0x6e4, 0x2e4, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT6__DISP1_DAT6         = IOMUX_PAD(0x6e4, 0x2e4, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG    = IOMUX_PAD(0x6e8, 0x2e8, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT7__DISP1_DAT7         = IOMUX_PAD(0x6e8, 0x2e8, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT8__BOOT_SRC0          = IOMUX_PAD(0x6ec, 0x2ec, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT8__DISP1_DAT8         = IOMUX_PAD(0x6ec, 0x2ec, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT9__BOOT_SRC1          = IOMUX_PAD(0x6f0, 0x2f0, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT9__DISP1_DAT9         = IOMUX_PAD(0x6f0, 0x2f0, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE   = IOMUX_PAD(0x6f4, 0x2f4, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT10__DISP1_DAT10       = IOMUX_PAD(0x6f4, 0x2f4, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2    = IOMUX_PAD(0x6f8, 0x2f8, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT11__DISP1_DAT11       = IOMUX_PAD(0x6f8, 0x2f8, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL      = IOMUX_PAD(0x6fc, 0x2fc, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT12__DISP1_DAT12       = IOMUX_PAD(0x6fc, 0x2fc, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0     = IOMUX_PAD(0x700, 0x300, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT13__DISP1_DAT13       = IOMUX_PAD(0x700, 0x300, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1     = IOMUX_PAD(0x704, 0x304, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT14__DISP1_DAT14       = IOMUX_PAD(0x704, 0x304, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH    = IOMUX_PAD(0x708, 0x308, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT15__DISP1_DAT15       = IOMUX_PAD(0x708, 0x308, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0   = IOMUX_PAD(0x70c, 0x30c, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT16__DISP1_DAT16       = IOMUX_PAD(0x70c, 0x30c, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1   = IOMUX_PAD(0x710, 0x310, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT17__DISP1_DAT17       = IOMUX_PAD(0x710, 0x310, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0  = IOMUX_PAD(0x714, 0x314, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT18__DISP1_DAT18       = IOMUX_PAD(0x714, 0x314, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT18__DISP2_PIN11       = IOMUX_PAD(0x714, 0x314, 5, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT18__DISP2_PIN5        = IOMUX_PAD(0x714, 0x314, 4, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1  = IOMUX_PAD(0x718, 0x318, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT19__DISP1_DAT19       = IOMUX_PAD(0x718, 0x318, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT19__DISP2_PIN12       = IOMUX_PAD(0x718, 0x318, 5, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT19__DISP2_PIN6        = IOMUX_PAD(0x718, 0x318, 4, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0    = IOMUX_PAD(0x71c, 0x31c, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT20__DISP1_DAT20       = IOMUX_PAD(0x71c, 0x31c, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT20__DISP2_PIN13       = IOMUX_PAD(0x71c, 0x31c, 5, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT20__DISP2_PIN7        = IOMUX_PAD(0x71c, 0x31c, 4, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1    = IOMUX_PAD(0x720, 0x320, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT21__DISP1_DAT21       = IOMUX_PAD(0x720, 0x320, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT21__DISP2_PIN14       = IOMUX_PAD(0x720, 0x320, 5, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT21__DISP2_PIN8        = IOMUX_PAD(0x720, 0x320, 4, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0    = IOMUX_PAD(0x724, 0x324, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT22__DISP1_DAT22       = IOMUX_PAD(0x724, 0x324, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT22__DISP2_D0_CS       = IOMUX_PAD(0x724, 0x324, 6, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT22__DISP2_DAT16       = IOMUX_PAD(0x724, 0x324, 5, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1    = IOMUX_PAD(0x728, 0x328, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT23__DISP1_DAT23       = IOMUX_PAD(0x728, 0x328, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT23__DISP2_D1_CS       = IOMUX_PAD(0x728, 0x328, 6, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT23__DISP2_DAT17       = IOMUX_PAD(0x728, 0x328, 5, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_DISP1_DAT23__DISP2_SER_CS      = IOMUX_PAD(0x728, 0x328, 4, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_DI1_PIN3__DI1_PIN3             = IOMUX_PAD(0x72c, 0x32c, 0, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_DI1_PIN2__DI1_PIN2             = IOMUX_PAD(0x734, 0x330, 0, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK     = IOMUX_PAD(0x754, 0x34c, 0, __NA_, 0, NO_PAD_CTRL),
@@ -195,6 +281,8 @@ enum {
        MX51_PAD_GPIO1_0__GPIO1_0               = IOMUX_PAD(0x7b4, 0x3ac, 1, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_GPIO1_0__SD1_CD                = IOMUX_PAD(0x7b4, 0x3ac, 0, __NA_, 0, MX51_ESDHC_PAD_CTRL),
        MX51_PAD_GPIO1_1__SD1_WP                = IOMUX_PAD(0x7b8, 0x3b0, 0, __NA_, 0, MX51_ESDHC_PAD_CTRL),
+       MX51_PAD_GPIO1_1__GPIO1_1               = IOMUX_PAD(0x7b8, 0x3b0, 1, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_1__CSPI_MISO             = IOMUX_PAD(0x7b8, 0x3b0, 2, 0x918, 2, MX51_ECSPI_PAD_CTRL),
        MX51_PAD_SD2_CMD__SD2_CMD               = IOMUX_PAD(0x7bc, 0x3b4, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL),
        MX51_PAD_SD2_CLK__SD2_CLK               = IOMUX_PAD(0x7c0, 0x3b8, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS),
        MX51_PAD_SD2_DATA0__SD2_DATA0           = IOMUX_PAD(0x7c4, 0x3bc, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL),
@@ -204,11 +292,24 @@ enum {
        MX51_PAD_GPIO1_2__GPIO1_2               = IOMUX_PAD(0x7d4, 0x3cc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_GPIO1_2__PWM1_PWMO             = IOMUX_PAD(0x7d4, 0x3cc, 1, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_GPIO1_3__GPIO1_3               = IOMUX_PAD(0x7d8, 0x3d0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
+       MX51_PAD_GPIO1_4__DISP2_EXT_CLK         = IOMUX_PAD(0x804, 0x3d8, 4, 0x908, 1, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_4__EIM_RDY               = IOMUX_PAD(0x804, 0x3d8, 3, 0x938, 1, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_4__GPIO1_4               = IOMUX_PAD(0x804, 0x3d8, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_4__WDOG1_WDOG_B          = IOMUX_PAD(0x804, 0x3d8, 2, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_GPIO1_5__GPIO1_5               = IOMUX_PAD(0x808, 0x3dc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_GPIO1_6__GPIO1_6               = IOMUX_PAD(0x80c, 0x3e0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_GPIO1_7__GPIO1_7               = IOMUX_PAD(0x810, 0x3e4, 0, __NA_, 0, MX51_GPIO_PAD_CTRL),
        MX51_PAD_GPIO1_7__SD2_WP                = IOMUX_PAD(0x810, 0x3e4, 6, __NA_, 0, MX51_ESDHC_PAD_CTRL),
+       MX51_PAD_GPIO1_8__CSI2_DATA_EN          = IOMUX_PAD(0x814, 0x3e8, 2, 0x99c, 2, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_8__GPIO1_8               = IOMUX_PAD(0x814, 0x3e8, 0, __NA_, 0, NO_PAD_CTRL),
        MX51_PAD_GPIO1_8__SD2_CD                = IOMUX_PAD(0x814, 0x3e8, 6, __NA_, 0, MX51_ESDHC_PAD_CTRL),
+       MX51_PAD_GPIO1_9__CCM_OUT_1             = IOMUX_PAD(0x818, 0x3ec, 3, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_9__DISP2_D1_CS           = IOMUX_PAD(0x818, 0x3ec, 2, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_9__DISP2_SER_CS          = IOMUX_PAD(0x818, 0x3ec, 7, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_9__GPIO1_9               = IOMUX_PAD(0x818, 0x3ec, 0, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_9__SD2_LCTL              = IOMUX_PAD(0x818, 0x3ec, 6, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_9__USBH3_OC              = IOMUX_PAD(0x818, 0x3ec, 1, __NA_, 0, NO_PAD_CTRL),
+       MX51_PAD_GPIO1_8__USBH3_PWR             = IOMUX_PAD(0x814, 0x3e8, 1, __NA_, 0, NO_PAD_CTRL),
        MX51_GRP_DDRPKS                         = IOMUX_PAD(0x820, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
        MX51_GRP_DRAM_B4                        = IOMUX_PAD(0x82c, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
        MX51_GRP_PKEDDR                         = IOMUX_PAD(0x838, __NA_, 0, __NA_, 0, NO_PAD_CTRL),
index 1b75fd1cfd13e697a622f36dbcd102743c6afd12..bc62621ea39de7ec9c912cc37c6ae22662a8dd15 100644 (file)
@@ -14,9 +14,9 @@
 #include <asm/imx-common/iomux-v3.h>
 
 /* Pad control groupings */
-#define MX53_UART_PAD_CTRL     (PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_HIGH | \
+#define MX53_UART_PAD_CTRL     MUX_PAD_CTRL(PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_HIGH | \
                                 PAD_CTL_SRE_FAST | PAD_CTL_HYS)
-#define MX53_SDHC_PAD_CTRL     (PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \
+#define MX53_SDHC_PAD_CTRL     MUX_PAD_CTRL(PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | \
                                 PAD_CTL_DSE_HIGH | PAD_CTL_SRE_FAST)
 
 /*
index ac7705b3b099dd28ad7639670ad3d78df668987d..4a6ba21bd634a5290e91dd8bd26dda011f559141 100644 (file)
@@ -15,6 +15,7 @@ u32 get_cpu_rev(void);
 unsigned imx_ddr_size(void);
 void sdelay(unsigned long);
 void set_chipselect_size(int const);
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
 
 /*
  * Initializes on-chip ethernet controllers.
index a6de5ee4bc12623a769b96a8f9bc86dde7b9e47f..1b6c140c20294f9928905e7c4947a41bd8b6f572 100644 (file)
@@ -49,9 +49,56 @@ enum enet_freq {
        ENET_125MHZ,
 };
 
+struct clk {
+       const char *name;
+       int id;
+       /* Source clock this clk depends on */
+       struct clk *parent;
+       /* Secondary clock to enable/disable with this clock */
+       struct clk *secondary;
+       /* Current clock rate */
+       unsigned long rate;
+       /* Reference count of clock enable/disable */
+       __s8 usecount;
+       /* Register bit position for clock's enable/disable control. */
+       u8 enable_shift;
+       /* Register address for clock's enable/disable control. */
+       void *enable_reg;
+       u32 flags;
+       /*
+        * Function ptr to recalculate the clock's rate based on parent
+        * clock's rate
+        */
+       void (*recalc) (struct clk *);
+       /*
+        * Function ptr to set the clock to a new rate. The rate must match a
+        * supported rate returned from round_rate. Leave blank if clock is not
+       * programmable
+        */
+       int (*set_rate) (struct clk *, unsigned long);
+       /*
+        * Function ptr to round the requested clock rate to the nearest
+        * supported rate that is less than or equal to the requested rate.
+        */
+       unsigned long (*round_rate) (struct clk *, unsigned long);
+       /*
+        * Function ptr to enable the clock. Leave blank if clock can not
+        * be gated.
+        */
+       int (*enable) (struct clk *);
+       /*
+        * Function ptr to disable the clock. Leave blank if clock can not
+        * be gated.
+        */
+       void (*disable) (struct clk *);
+       /* Function ptr to set the parent clock of the clock. */
+       int (*set_parent) (struct clk *, struct clk *);
+};
+
 u32 imx_get_uartclk(void);
 u32 imx_get_fecclk(void);
 unsigned int mxc_get_clock(enum mxc_clock clk);
+int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk);
 void setup_gpmi_io_clk(u32 cfg);
 void hab_caam_clock_enable(unsigned char enable);
 void enable_ocotp_clk(unsigned char enable);
@@ -69,4 +116,12 @@ int enable_fec_anatop_clock(enum enet_freq freq);
 void enable_enet_clk(unsigned char enable);
 void enable_qspi_clk(int qspi_num);
 void enable_thermal_clk(void);
+void ipu_clk_enable(void);
+void ipu_clk_disable(void);
+void ipu_di_clk_enable(int di);
+void ipu_di_clk_disable(int di);
+void ldb_clk_enable(int ldb);
+void ldb_clk_disable(int ldb);
+void ocotp_clk_enable(void);
+void ocotp_clk_disable(void);
 #endif /* __ASM_ARCH_CLOCK_H */
index 39f3c0707b8ee38eb9eda7e891a64e9f913298cc..d882d3b008c9c782699aca531fe42b3dacaa068d 100644 (file)
@@ -55,62 +55,14 @@ struct mxc_ccm_reg {
        u32 CCGR6;      /* 0x0080 */
        u32 CCGR7;
        u32 cmeor;
-       u32 resv[0xfdd];
-       u32 analog_pll_sys;                     /* 0x4000 */
-       u32 analog_pll_sys_set;
-       u32 analog_pll_sys_clr;
-       u32 analog_pll_sys_tog;
-       u32 analog_usb1_pll_480_ctrl;           /* 0x4010 */
-       u32 analog_usb1_pll_480_ctrl_set;
-       u32 analog_usb1_pll_480_ctrl_clr;
-       u32 analog_usb1_pll_480_ctrl_tog;
-       u32 analog_reserved0[4];
-       u32 analog_pll_528;                     /* 0x4030 */
-       u32 analog_pll_528_set;
-       u32 analog_pll_528_clr;
-       u32 analog_pll_528_tog;
-       u32 analog_pll_528_ss;                  /* 0x4040 */
-       u32 analog_reserved1[3];
-       u32 analog_pll_528_num;                 /* 0x4050 */
-       u32 analog_reserved2[3];
-       u32 analog_pll_528_denom;               /* 0x4060 */
-       u32 analog_reserved3[3];
-       u32 analog_pll_audio;                   /* 0x4070 */
-       u32 analog_pll_audio_set;
-       u32 analog_pll_audio_clr;
-       u32 analog_pll_audio_tog;
-       u32 analog_pll_audio_num;               /* 0x4080*/
-       u32 analog_reserved4[3];
-       u32 analog_pll_audio_denom;             /* 0x4090 */
-       u32 analog_reserved5[3];
-       u32 analog_pll_video;                   /* 0x40a0 */
-       u32 analog_pll_video_set;
-       u32 analog_pll_video_clr;
-       u32 analog_pll_video_tog;
-       u32 analog_pll_video_num;               /* 0x40b0 */
-       u32 analog_reserved6[3];
-       u32 analog_pll_video_denom;             /* 0x40c0 */
-       u32 analog_reserved7[7];
-       u32 analog_pll_enet;                    /* 0x40e0 */
-       u32 analog_pll_enet_set;
-       u32 analog_pll_enet_clr;
-       u32 analog_pll_enet_tog;
-       u32 analog_pfd_480;                     /* 0x40f0 */
-       u32 analog_pfd_480_set;
-       u32 analog_pfd_480_clr;
-       u32 analog_pfd_480_tog;
-       u32 analog_pfd_528;                     /* 0x4100 */
-       u32 analog_pfd_528_set;
-       u32 analog_pfd_528_clr;
-       u32 analog_pfd_528_tog;
 };
 #endif
 
 /* Define the bits in register CCR */
 #define MXC_CCM_CCR_RBC_EN                             (1 << 27)
-#define MXC_CCM_CCR_REG_BYPASS_CNT_MASK                        (0x3F << 21)
+#define MXC_CCM_CCR_REG_BYPASS_CNT_MASK                        (0x3F << CCR_REG_BYPASS_CNT_OFFSET)
 #define MXC_CCM_CCR_REG_BYPASS_CNT_OFFSET              21
-#define MXC_CCM_CCR_WB_COUNT_MASK                      0x7
+#define MXC_CCM_CCR_WB_COUNT_MASK                      (0x7 << MXC_CCM_CCR_WB_COUNT_OFFSET)
 #define MXC_CCM_CCR_WB_COUNT_OFFSET                    (1 << 16)
 #define MXC_CCM_CCR_COSC_EN                            (1 << 12)
 #ifdef CONFIG_MX6SX
@@ -143,57 +95,57 @@ struct mxc_ccm_reg {
 
 /* Define the bits in register CACRR */
 #define MXC_CCM_CACRR_ARM_PODF_OFFSET                  0
-#define MXC_CCM_CACRR_ARM_PODF_MASK                    0x7
+#define MXC_CCM_CACRR_ARM_PODF_MASK                    (0x7 << MXC_CCM_CACRR_ARM_PODF_OFFSET)
 
 /* Define the bits in register CBCDR */
-#define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK            (0x7 << 27)
+#define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK            (0x7 << MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET)
 #define MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET          27
 #define MXC_CCM_CBCDR_PERIPH2_CLK2_SEL                 (1 << 26)
 #define MXC_CCM_CBCDR_PERIPH_CLK_SEL                   (1 << 25)
 #ifndef CONFIG_MX6SX
-#define MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK               (0x7 << 19)
+#define MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK               (0x7 << MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET)
 #define MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET             19
 #endif
-#define MXC_CCM_CBCDR_AXI_PODF_MASK                    (0x7 << 16)
+#define MXC_CCM_CBCDR_AXI_PODF_MASK                    (0x7 << MXC_CCM_CBCDR_AXI_PODF_OFFSET)
 #define MXC_CCM_CBCDR_AXI_PODF_OFFSET                  16
-#define MXC_CCM_CBCDR_AHB_PODF_MASK                    (0x7 << 10)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK                    (0x7 << MXC_CCM_CBCDR_AHB_PODF_OFFSET)
 #define MXC_CCM_CBCDR_AHB_PODF_OFFSET                  10
-#define MXC_CCM_CBCDR_IPG_PODF_MASK                    (0x3 << 8)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK                    (0x3 << MXC_CCM_CBCDR_IPG_PODF_OFFSET)
 #define MXC_CCM_CBCDR_IPG_PODF_OFFSET                  8
 #define MXC_CCM_CBCDR_AXI_ALT_SEL                      (1 << 7)
 #define MXC_CCM_CBCDR_AXI_SEL                          (1 << 6)
-#define MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK               (0x7 << 3)
+#define MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK               (0x7 << MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET)
 #define MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET             3
-#define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK           (0x7 << 0)
+#define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK           (0x7 << MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET)
 #define MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET         0
 
 /* Define the bits in register CBCMR */
-#define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK           (0x7 << 29)
+#define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_MASK           (0x7 << MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET)
 #define MXC_CCM_CBCMR_GPU3D_SHADER_PODF_OFFSET         29
-#define MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK             (0x7 << 26)
+#define MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK             (0x7 << MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET)
 #define MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET           26
-#define MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK             (0x7 << 23)
+#define MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK             (0x7 << MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET)
 #define MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET           23
-#define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK         (0x3 << 21)
+#define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK         (0x3 << MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET)
 #define MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET       21
 #define MXC_CCM_CBCMR_PRE_PERIPH2_CLK2_SEL             (1 << 20)
-#define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK          (0x3 << 18)
+#define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK          (0x3 << MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET)
 #define MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET                18
 #ifndef CONFIG_MX6SX
-#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK               (0x3 << 16)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK               (0x3 << MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET)
 #define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET             16
-#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK             (0x3 << 14)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK             (0x3 << MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET)
 #define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET           14
 #endif
-#define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK             (0x3 << 12)
+#define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK             (0x3 << MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET)
 #define MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET           12
 #ifndef CONFIG_MX6SX
 #define MXC_CCM_CBCMR_VDOAXI_CLK_SEL                   (1 << 11)
 #endif
 #define MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL                 (1 << 10)
-#define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK                (0x3 << 8)
+#define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_MASK                (0x3 << MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_OFFSET)
 #define MXC_CCM_CBCMR_GPU3D_SHADER_CLK_SEL_OFFSET      8
-#define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK          (0x3 << 4)
+#define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_MASK          (0x3 << MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_OFFSET)
 #define MXC_CCM_CBCMR_GPU3D_CORE_CLK_SEL_OFFSET                4
 #ifndef CONFIG_MX6SX
 #define MXC_CCM_CBCMR_GPU3D_AXI_CLK_SEL                        (1 << 1)
@@ -201,212 +153,211 @@ struct mxc_ccm_reg {
 #endif
 
 /* Define the bits in register CSCMR1 */
-#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK              (0x3 << 29)
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK              (0x3 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET)
 #define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET            29
 #ifdef CONFIG_MX6SX
-#define MXC_CCM_CSCMR1_QSPI1_PODF_MASK                 (0x7 << 26)
+#define MXC_CCM_CSCMR1_QSPI1_PODF_MASK                 (0x7 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET)
 #define MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET               26
 #else
-#define MXC_CCM_CSCMR1_ACLK_EMI_MASK                   (0x3 << 27)
+#define MXC_CCM_CSCMR1_ACLK_EMI_MASK                   (0x3 << MXC_CCM_CSCMR1_ACLK_EMI_OFFSET)
 #define MXC_CCM_CSCMR1_ACLK_EMI_OFFSET                 27
 #endif
-#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK         (0x7 << 23)
+#define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK         (0x7 << MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET)
 #define MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET       23
 /* ACLK_EMI_PODF is LCFIF2_PODF on MX6SX */
-#define MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK              (0x7 << 20)
+#define MXC_CCM_CSCMR1_ACLK_EMI_PODF_MASK              (0x7 << MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET)
 #define MXC_CCM_CSCMR1_ACLK_EMI_PODF_OFFSET            20
 #define MXC_CCM_CSCMR1_USDHC4_CLK_SEL                  (1 << 19)
 #define MXC_CCM_CSCMR1_USDHC3_CLK_SEL                  (1 << 18)
 #define MXC_CCM_CSCMR1_USDHC2_CLK_SEL                  (1 << 17)
 #define MXC_CCM_CSCMR1_USDHC1_CLK_SEL                  (1 << 16)
-#define MXC_CCM_CSCMR1_SSI3_CLK_SEL_MASK               (0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL_MASK               (0x3 << MXC_CCM_CSCMR1_SSI3_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCMR1_SSI3_CLK_SEL_OFFSET             14
-#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK               (0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK               (0x3 << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET             12
-#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK               (0x3 << 10)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK               (0x3 << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET             10
 #ifdef CONFIG_MX6SX
-#define MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK              (0x7 << 7)
+#define MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK              (0x7 << MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET            7
 #endif
 #if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
-#define MXC_CCM_CSCMR1_PER_CLK_SEL_MASK                        (1 << 6)
+#define MXC_CCM_CSCMR1_PER_CLK_SEL_MASK                        (1 << MXC_CCM_CSCMR1_PER_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCMR1_PER_CLK_SEL_OFFSET              6
 #endif
-#define MXC_CCM_CSCMR1_PERCLK_PODF_MASK                        0x3F
+#define MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET              0
+#define MXC_CCM_CSCMR1_PERCLK_PODF_MASK                        (0x3F << MXC_CCM_CSCMR1_PERCLK_PODF_OFFSET)
 
 /* Define the bits in register CSCMR2 */
 #ifdef CONFIG_MX6SX
-#define MXC_CCM_CSCMR2_VID_CLK_SEL_MASK                        (0x7 << 21)
+#define MXC_CCM_CSCMR2_VID_CLK_SEL_MASK                        (0x7 << MXC_CCM_CSCMR2_VID_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCMR2_VID_CLK_SEL_OFFSET              21
 #endif
-#define MXC_CCM_CSCMR2_ESAI_PRE_SEL_MASK               (0x3 << 19)
+#define MXC_CCM_CSCMR2_ESAI_PRE_SEL_MASK               (0x3 << MXC_CCM_CSCMR2_ESAI_PRE_SEL_OFFSET)
 #define MXC_CCM_CSCMR2_ESAI_PRE_SEL_OFFSET             19
 #define MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV                 (1 << 11)
 #define MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV                 (1 << 10)
 #ifdef CONFIG_MX6SX
-#define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK                        (0x3 << 8)
+#define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK                        (0x3 << MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET              8
-#define MXC_CCM_CSCMR2_CAN_CLK_PODF_MASK               (0x3F << 2)
+#define MXC_CCM_CSCMR2_CAN_CLK_PODF_MASK               (0x3F << MXC_CCM_CSCMR2_CAN_CLK_PODF_OFFSET)
 #define MXC_CCM_CSCMR2_CAN_CLK_PODF_OFFSET             2
 #else
-#define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK                        (0x3F << 2)
+#define MXC_CCM_CSCMR2_CAN_CLK_SEL_MASK                        (0x3F << MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCMR2_CAN_CLK_SEL_OFFSET              2
 #endif
 
 /* Define the bits in register CSCDR1 */
 #ifndef CONFIG_MX6SX
-#define MXC_CCM_CSCDR1_VPU_AXI_PODF_MASK               (0x7 << 25)
+#define MXC_CCM_CSCDR1_VPU_AXI_PODF_MASK               (0x7 << MXC_CCM_CSCDR1_VPU_AXI_PODF_OFFSET)
 #define MXC_CCM_CSCDR1_VPU_AXI_PODF_OFFSET             25
 #endif
-#define MXC_CCM_CSCDR1_USDHC4_PODF_MASK                        (0x7 << 22)
+#define MXC_CCM_CSCDR1_USDHC4_PODF_MASK                        (0x7 << MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET)
 #define MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET              22
-#define MXC_CCM_CSCDR1_USDHC3_PODF_MASK                        (0x7 << 19)
+#define MXC_CCM_CSCDR1_USDHC3_PODF_MASK                        (0x7 << MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET)
 #define MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET              19
-#define MXC_CCM_CSCDR1_USDHC2_PODF_MASK                        (0x7 << 16)
+#define MXC_CCM_CSCDR1_USDHC2_PODF_MASK                        (0x7 << MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET)
 #define MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET              16
-#define MXC_CCM_CSCDR1_USDHC1_PODF_MASK                        (0x7 << 11)
+#define MXC_CCM_CSCDR1_USDHC1_PODF_MASK                        (0x7 << MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET)
 #define MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET              11
 #ifndef CONFIG_MX6SX
 #define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET          8
-#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK            (0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK            (0x7 << MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET)
 #define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET          6
-#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK            (0x3 << 6)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK            (0x3 << MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET)
 #endif
 #ifdef CONFIG_MX6SL
-#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK              0x1F
-#define MXC_CCM_CSCDR1_UART_CLK_SEL                    (1 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK              (0x1F << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET)
+#define MXC_CCM_CSCDR1_UART_CLK_SEL                    (1 << MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET)
 #else
-#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK              0x3F
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK              (0x3F << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET)
 #ifdef CONFIG_MX6SX
-#define MXC_CCM_CSCDR1_UART_CLK_SEL                    (1 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_SEL                    (1 << MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET)
 #endif
 #endif
+#define MXC_CCM_CSCDR1_UART_CLK_SEL_OFFSET             6
 #define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET            0
 
 /* Define the bits in register CS1CDR */
-#define MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK              (0x3F << 25)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PODF_MASK              (0x3F << MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET)
 #define MXC_CCM_CS1CDR_ESAI_CLK_PODF_OFFSET            25
-#define MXC_CCM_CS1CDR_SSI3_CLK_PRED_MASK              (0x7 << 22)
+#define MXC_CCM_CS1CDR_SSI3_CLK_PRED_MASK              (0x7 << MXC_CCM_CS1CDR_SSI3_CLK_PRED_OFFSET)
 #define MXC_CCM_CS1CDR_SSI3_CLK_PRED_OFFSET            22
-#define MXC_CCM_CS1CDR_SSI3_CLK_PODF_MASK              (0x3F << 16)
+#define MXC_CCM_CS1CDR_SSI3_CLK_PODF_MASK              (0x3F << MXC_CCM_CS1CDR_SSI3_CLK_PODF_OFFSET)
 #define MXC_CCM_CS1CDR_SSI3_CLK_PODF_OFFSET            16
-#define MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK              (0x3 << 9)
+#define MXC_CCM_CS1CDR_ESAI_CLK_PRED_MASK              (0x3 << MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET)
 #define MXC_CCM_CS1CDR_ESAI_CLK_PRED_OFFSET            9
-#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK              (0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK              (0x7 << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET)
 #define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET            6
-#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK              0x3F
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK              (0x3F << MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET)
 #define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET            0
 
 /* Define the bits in register CS2CDR */
 #ifdef CONFIG_MX6SX
-#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK             (0x3F << 21)
-#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF_OFFSET           21
-#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF(v)                       (((v) & 0x3f) << 21)
-#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK             (0x7 << 18)
-#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED_OFFSET           18
-#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED(v)                       (((v) & 0x7) << 18)
-#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK              (0x7 << 15)
-#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL_OFFSET            15
-#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL(v)                        (((v) & 0x7) << 15)
+#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK             (0x3F << MXC_CCM_CS2CDR_QSPI2_CLK_PODF_OFFSET)
+#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF_OFFSET           21
+#define MXC_CCM_CS2CDR_QSPI2_CLK_PODF(v)               (((v) & 0x3f) << MXC_CCM_CS2CDR_QSPI2_CLK_PODF_OFFSET)
+#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK             (0x7 << MXC_CCM_CS2CDR_QSPI2_CLK_PRED_OFFSET)
+#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED_OFFSET           18
+#define MXC_CCM_CS2CDR_QSPI2_CLK_PRED(v)               (((v) & 0x7) << MXC_CCM_CS2CDR_QSPI2_CLK_PRED_OFFSET)
+#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK              (0x7 << MXC_CCM_CS2CDR_QSPI2_CLK_SEL_OFFSET)
+#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL_OFFSET            15
+#define MXC_CCM_CS2CDR_QSPI2_CLK_SEL(v)                        (((v) & 0x7) << MXC_CCM_CS2CDR_QSPI2_CLK_SEL_OFFSET)
 #else
-#define MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK              (0x3F << 21)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK              (0x3F << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET)
 #define MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET            21
-#define MXC_CCM_CS2CDR_ENFC_CLK_PODF(v)                        (((v) & 0x3f) << 21)
-#define MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK              (0x7 << 18)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PODF(v)                        (((v) & 0x3f) << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK              (0x7 << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET)
 #define MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET            18
-#define MXC_CCM_CS2CDR_ENFC_CLK_PRED(v)                        (((v) & 0x7) << 18)
-#define MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK               (0x3 << 16)
+#define MXC_CCM_CS2CDR_ENFC_CLK_PRED(v)                        (((v) & 0x7) << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET)
+#define MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK               (0x3 << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET)
 #define MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET             16
-#define MXC_CCM_CS2CDR_ENFC_CLK_SEL(v)                 (((v) & 0x3) << 16)
+#define MXC_CCM_CS2CDR_ENFC_CLK_SEL(v)                 (((v) & 0x3) << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET)
 #endif
-#define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK            (0x7 << 12)
+#define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK            (0x7 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)
 #define MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET          12
-#define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK            (0x7 << 9)
+#define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK            (0x7 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
 #define MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET          9
-#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK              (0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK              (0x7 << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET)
 #define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET            6
-#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK              0x3F
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK              (0x3F << MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET)
 #define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET            0
 
 /* Define the bits in register CDCDR */
 #ifndef CONFIG_MX6SX
-#define MXC_CCM_CDCDR_HSI_TX_PODF_MASK                 (0x7 << 29)
+#define MXC_CCM_CDCDR_HSI_TX_PODF_MASK                 (0x7 << MXC_CCM_CDCDR_HSI_TX_PODF_OFFSET)
 #define MXC_CCM_CDCDR_HSI_TX_PODF_OFFSET               29
-#define MXC_CCM_CDCDR_HSI_TX_CLK_SEL                   (1 << 28)
+#define MXC_CCM_CDCDR_HSI_TX_CLK_SEL_MASK              (1 << MXC_CCM_CDCDR_HSI_TX_CLK_SEL_OFFSET)
+#define MXC_CCM_CDCDR_HSI_TX_CLK_SEL_OFFSET            28
 #endif
-#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK             (0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK             (0x7 << MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET)
 #define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET           25
-#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK             (0x7 << 22)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK             (0x7 << MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET)
 #define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET           22
-#define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_MASK              (0x3 << 20)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_MASK              (0x3 << MXC_CCM_CDCDR_SPDIF0_CLK_SEL_OFFSET)
 #define MXC_CCM_CDCDR_SPDIF0_CLK_SEL_OFFSET            20
-#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK             (0x7 << 12)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK             (0x7 << MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET)
 #define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET           12
-#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK             (0x7 << 9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK             (0x7 << MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET)
 #define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET           9
-#define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_MASK              (0x3 << 7)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_MASK              (0x3 << MXC_CCM_CDCDR_SPDIF1_CLK_SEL_OFFSET)
 #define MXC_CCM_CDCDR_SPDIF1_CLK_SEL_OFFSET            7
 
 /* Define the bits in register CHSCCDR */
 #ifdef CONFIG_MX6SX
-#define MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK          (0x7 << 15)
+#define MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK          (0x7 << MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET                15
-#define MXC_CCM_CHSCCDR_ENET_PODF_MASK                 (0x7 << 12)
+#define MXC_CCM_CHSCCDR_ENET_PODF_MASK                 (0x7 << MXC_CCM_CHSCCDR_ENET_PODF_OFFSET)
 #define MXC_CCM_CHSCCDR_ENET_PODF_OFFSET               12
-#define MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK              (0x7 << 9)
+#define MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK              (0x7 << MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET            9
-#define MXC_CCM_CHSCCDR_M4_PRE_CLK_SEL_MASK            (0x7 << 6)
+#define MXC_CCM_CHSCCDR_M4_PRE_CLK_SEL_MASK            (0x7 << MXC_CCM_CHSCCDR_M4_PRE_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_M4_PRE_CLK_SEL_OFFSET          6
-#define MXC_CCM_CHSCCDR_M4_PODF_MASK                   (0x7 << 3)
+#define MXC_CCM_CHSCCDR_M4_PODF_MASK                   (0x7 << MXC_CCM_CHSCCDR_M4_PODF_OFFSET)
 #define MXC_CCM_CHSCCDR_M4_PODF_OFFSET                 3
-#define MXC_CCM_CHSCCDR_M4_CLK_SEL_MASK                        (0x7)
+#define MXC_CCM_CHSCCDR_M4_CLK_SEL_MASK                        (0x7 << MXC_CCM_CHSCCDR_M4_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_M4_CLK_SEL_OFFSET              0
 #else
-#define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK      (0x7 << 15)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MASK      (0x7 << MXC_CCM_CHSCCDR_DI1_PRE_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_OFFSET    15
-#define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK             (0x7 << 12)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_MASK             (0x7 << MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI1_PODF_OFFSET           12
-#define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK          (0x7 << 9)
+#define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_MASK          (0x7 << MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET                9
-#define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK      (0x7 << 6)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK      (0x7 << MXC_CCM_CHSCCDR_DI0_PRE_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET    6
-#define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK             (0x7 << 3)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK             (0x7 << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET           3
-#define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK          (0x7)
+#define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK          (0x7 << MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
 #define MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET                0
 #endif
 
-#define CHSCCDR_CLK_SEL_LDB_DI0                                3
-#define CHSCCDR_PODF_DIVIDE_BY_3                       2
-#define CHSCCDR_IPU_PRE_CLK_540M_PFD                   5
-
 /* Define the bits in register CSCDR2 */
-#define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK             (0x3F << 19)
+#define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK             (0x3F << MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET)
 #define MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET           19
 /* All IPU2_DI1 are LCDIF1 on MX6SX */
-#define MXC_CCM_CHSCCDR_IPU2_DI1_PRE_CLK_SEL_MASK      (0x7 << 15)
-#define MXC_CCM_CHSCCDR_IPU2_DI1_PRE_CLK_SEL_OFFSET    15
-#define MXC_CCM_CHSCCDR_IPU2_DI1_PODF_MASK             (0x7 << 12)
-#define MXC_CCM_CHSCCDR_IPU2_DI1_PODF_OFFSET           12
-#define MXC_CCM_CHSCCDR_IPU2_DI1_CLK_SEL_MASK          (0x7 << 9)
-#define MXC_CCM_CHSCCDR_IPU2_DI1_CLK_SEL_OFFSET                9
+#define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_MASK       (0x7 << MXC_CCM_CSCDR2_DI1_PRE_CLK_SEL_OFFSET)
+#define MXC_CCM_CSCDR2_IPU2_DI1_PRE_CLK_SEL_OFFSET     15
+#define MXC_CCM_CSCDR2_IPU2_DI1_PODF_MASK              (0x7 << MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET)
+#define MXC_CCM_CSCDR2_IPU2_DI1_PODF_OFFSET            12
+#define MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_MASK           (0x7 << MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_OFFSET)
+#define MXC_CCM_CSCDR2_IPU2_DI1_CLK_SEL_OFFSET         9
 /* All IPU2_DI0 are LCDIF2 on MX6SX */
-#define MXC_CCM_CHSCCDR_IPU2_DI0_PRE_CLK_SEL_MASK      (0x7 << 6)
-#define MXC_CCM_CHSCCDR_IPU2_DI0_PRE_CLK_SEL_OFFSET    6
-#define MXC_CCM_CHSCCDR_IPU2_DI0_PODF_MASK             (0x7 << 3)
-#define MXC_CCM_CHSCCDR_IPU2_DI0_PODF_OFFSET           3
-#define MXC_CCM_CHSCCDR_IPU2_DI0_CLK_SEL_MASK          0x7
-#define MXC_CCM_CHSCCDR_IPU2_DI0_CLK_SEL_OFFSET                0
+#define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_MASK       (0x7 << MXC_CCM_CSCDR2_DI0_PRE_CLK_SEL_OFFSET)
+#define MXC_CCM_CSCDR2_IPU2_DI0_PRE_CLK_SEL_OFFSET     6
+#define MXC_CCM_CSCDR2_IPU2_DI0_PODF_MASK              (0x7 << MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET)
+#define MXC_CCM_CSCDR2_IPU2_DI0_PODF_OFFSET            3
+#define MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_MASK           (0x7 << MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_OFFSET)
+#define MXC_CCM_CSCDR2_IPU2_DI0_CLK_SEL_OFFSET         0
 
 /* Define the bits in register CSCDR3 */
-#define MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK              (0x7 << 16)
+#define MXC_CCM_CSCDR3_IPU2_HSP_PODF_MASK              (0x7 << MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET)
 #define MXC_CCM_CSCDR3_IPU2_HSP_PODF_OFFSET            16
-#define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK           (0x3 << 14)
+#define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_MASK           (0x3 << MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCDR3_IPU2_HSP_CLK_SEL_OFFSET         14
-#define MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK              (0x7 << 11)
+#define MXC_CCM_CSCDR3_IPU1_HSP_PODF_MASK              (0x7 << MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET)
 #define MXC_CCM_CSCDR3_IPU1_HSP_PODF_OFFSET            11
-#define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK           (0x3 << 9)
+#define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_MASK           (0x3 << MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET)
 #define MXC_CCM_CSCDR3_IPU1_HSP_CLK_SEL_OFFSET         9
 
 /* Define the bits in register CDHIPR */
@@ -418,7 +369,7 @@ struct mxc_ccm_reg {
 #define MXC_CCM_CDHIPR_PERIPH2_CLK_SEL_BUSY            (1 << 3)
 #define MXC_CCM_CDHIPR_MMDC_CH1_PODF_BUSY              (1 << 2)
 #define MXC_CCM_CDHIPR_AHB_PODF_BUSY                   (1 << 1)
-#define MXC_CCM_CDHIPR_AXI_PODF_BUSY                   1
+#define MXC_CCM_CDHIPR_AXI_PODF_BUSY                   (1 << 0)
 
 /* Define the bits in register CLPCR */
 #define MXC_CCM_CLPCR_MASK_L2CC_IDLE                   (1 << 27)
@@ -436,18 +387,18 @@ struct mxc_ccm_reg {
 #endif
 #define MXC_CCM_CLPCR_WB_PER_AT_LPM                    (1 << 16)
 #define MXC_CCM_CLPCR_COSC_PWRDOWN                     (1 << 11)
-#define MXC_CCM_CLPCR_STBY_COUNT_MASK                  (0x3 << 9)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK                  (0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET)
 #define MXC_CCM_CLPCR_STBY_COUNT_OFFSET                        9
 #define MXC_CCM_CLPCR_VSTBY                            (1 << 8)
 #define MXC_CCM_CLPCR_DIS_REF_OSC                      (1 << 7)
 #define MXC_CCM_CLPCR_SBYOS                            (1 << 6)
 #define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM               (1 << 5)
 #ifndef CONFIG_MX6SX
-#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK                        (0x3 << 3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK                        (0x3 << MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET)
 #define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET              3
 #define MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY          (1 << 2)
 #endif
-#define MXC_CCM_CLPCR_LPM_MASK                         0x3
+#define MXC_CCM_CLPCR_LPM_MASK                         (0x3 << MXC_CCM_CLPCR_LPM_OFFSET)
 #define MXC_CCM_CLPCR_LPM_OFFSET                       0
 
 /* Define the bits in register CISR */
@@ -461,7 +412,7 @@ struct mxc_ccm_reg {
 #define MXC_CCM_CISR_PERIPH2_CLK_SEL_LOADED            (1 << 19)
 #define MXC_CCM_CISR_AXI_PODF_LOADED                   (1 << 17)
 #define MXC_CCM_CISR_COSC_READY                                (1 << 6)
-#define MXC_CCM_CISR_LRF_PLL                           1
+#define MXC_CCM_CISR_LRF_PLL                           (1 << 0)
 
 /* Define the bits in register CIMR */
 #define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED              (1 << 26)
@@ -474,26 +425,26 @@ struct mxc_ccm_reg {
 #define MXC_CCM_CIMR_MASK_PERIPH2_CLK_SEL_LOADED       (1 << 19)
 #define MXC_CCM_CIMR_MASK_AXI_PODF_LOADED              (1 << 17)
 #define MXC_CCM_CIMR_MASK_COSC_READY                   (1 << 6)
-#define MXC_CCM_CIMR_MASK_LRF_PLL                      1
+#define MXC_CCM_CIMR_MASK_LRF_PLL                      (1 << 0)
 
 /* Define the bits in register CCOSR */
 #define MXC_CCM_CCOSR_CKO2_EN_OFFSET                   (1 << 24)
-#define MXC_CCM_CCOSR_CKO2_DIV_MASK                    (0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK                    (0x7 << MXC_CCM_CCOSR_CKO2_DIV_OFFSET)
 #define MXC_CCM_CCOSR_CKO2_DIV_OFFSET                  21
 #define MXC_CCM_CCOSR_CKO2_SEL_OFFSET                  16
-#define MXC_CCM_CCOSR_CKO2_SEL_MASK                    (0x1F << 16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK                    (0x1F << MXC_CCM_CCOSR_CKO2_SEL_OFFSET)
 #define MXC_CCM_CCOSR_CLK_OUT_SEL                      (0x1 << 8)
 #define MXC_CCM_CCOSR_CKOL_EN                          (0x1 << 7)
-#define MXC_CCM_CCOSR_CKOL_DIV_MASK                    (0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK                    (0x7 << MXC_CCM_CCOSR_CKOL_DIV_OFFSET)
 #define MXC_CCM_CCOSR_CKOL_DIV_OFFSET                  4
-#define MXC_CCM_CCOSR_CKOL_SEL_MASK                    0xF
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK                    (0xF << MXC_CCM_CCOSR_CKOL_SEL_OFFSET)
 #define MXC_CCM_CCOSR_CKOL_SEL_OFFSET                  0
 
 /* Define the bits in registers CGPR */
 #define MXC_CCM_CGPR_FAST_PLL_EN                       (1 << 16)
 #define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE            (1 << 4)
 #define MXC_CCM_CGPR_MMDC_EXT_CLK_DIS                  (1 << 2)
-#define MXC_CCM_CGPR_PMIC_DELAY_SCALER                 1
+#define MXC_CCM_CGPR_PMIC_DELAY_SCALER                 (1 << 0)
 
 /* Define the bits in registers CCGRx */
 #define MXC_CCM_CCGR_CG_MASK                           3
@@ -726,341 +677,675 @@ struct mxc_ccm_reg {
 #define MXC_CCM_CCGR5_SAI2_MASK                                (3 << MXC_CCM_CCGR5_SAI2_OFFSET)
 #endif
 
-#define MXC_CCM_CCGR6_USBOH3_OFFSET            0
-#define MXC_CCM_CCGR6_USBOH3_MASK              (3 << MXC_CCM_CCGR6_USBOH3_OFFSET)
-#define MXC_CCM_CCGR6_USDHC1_OFFSET            2
-#define MXC_CCM_CCGR6_USDHC1_MASK              (3 << MXC_CCM_CCGR6_USDHC1_OFFSET)
-#define MXC_CCM_CCGR6_USDHC2_OFFSET            4
-#define MXC_CCM_CCGR6_USDHC2_MASK              (3 << MXC_CCM_CCGR6_USDHC2_OFFSET)
-#define MXC_CCM_CCGR6_USDHC3_OFFSET            6
-#define MXC_CCM_CCGR6_USDHC3_MASK              (3 << MXC_CCM_CCGR6_USDHC3_OFFSET)
-#define MXC_CCM_CCGR6_USDHC4_OFFSET            8
-#define MXC_CCM_CCGR6_USDHC4_MASK              (3 << MXC_CCM_CCGR6_USDHC4_OFFSET)
-#define MXC_CCM_CCGR6_EMI_SLOW_OFFSET          10
-#define MXC_CCM_CCGR6_EMI_SLOW_MASK            (3 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET)
+#define MXC_CCM_CCGR6_USBOH3_OFFSET                    0
+#define MXC_CCM_CCGR6_USBOH3_MASK                      (3 << MXC_CCM_CCGR6_USBOH3_OFFSET)
+#define MXC_CCM_CCGR6_USDHC1_OFFSET                    2
+#define MXC_CCM_CCGR6_USDHC1_MASK                      (3 << MXC_CCM_CCGR6_USDHC1_OFFSET)
+#define MXC_CCM_CCGR6_USDHC2_OFFSET                    4
+#define MXC_CCM_CCGR6_USDHC2_MASK                      (3 << MXC_CCM_CCGR6_USDHC2_OFFSET)
+#define MXC_CCM_CCGR6_USDHC3_OFFSET                    6
+#define MXC_CCM_CCGR6_USDHC3_MASK                      (3 << MXC_CCM_CCGR6_USDHC3_OFFSET)
+#define MXC_CCM_CCGR6_USDHC4_OFFSET                    8
+#define MXC_CCM_CCGR6_USDHC4_MASK                      (3 << MXC_CCM_CCGR6_USDHC4_OFFSET)
+#define MXC_CCM_CCGR6_EMI_SLOW_OFFSET                  10
+#define MXC_CCM_CCGR6_EMI_SLOW_MASK                    (3 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET)
+#define MXC_CCM_CCGR6_VDOAXICLK_OFFSET                 12
+#define MXC_CCM_CCGR6_VDOAXICLK_MASK                   (3 << MXC_CCM_CCGR6_VDOAXICLK_OFFSET)
+
+#define ANATOP_PFD_480_PFD0_FRAC_SHIFT                 0
+#define ANATOP_PFD_480_PFD0_FRAC_MASK                  (0x3f << ANATOP_PFD_480_PFD0_FRAC_SHIFT)
+#define ANATOP_PFD_480_PFD0_STABLE_SHIFT               6
+#define ANATOP_PFD_480_PFD0_STABLE_MASK                        (1 << ANATOP_PFD_480_PFD0_STABLE_SHIFT)
+#define ANATOP_PFD_480_PFD0_CLKGATE_SHIFT              7
+#define ANATOP_PFD_480_PFD0_CLKGATE_MASK               (1 << ANATOP_PFD_480_PFD0_CLKGATE_SHIFT)
+#define ANATOP_PFD_480_PFD1_FRAC_SHIFT                 8
+#define ANATOP_PFD_480_PFD1_FRAC_MASK                  (0x3f << ANATOP_PFD_480_PFD1_FRAC_SHIFT)
+#define ANATOP_PFD_480_PFD1_STABLE_SHIFT               14
+#define ANATOP_PFD_480_PFD1_STABLE_MASK                        (1 << ANATOP_PFD_480_PFD1_STABLE_SHIFT)
+#define ANATOP_PFD_480_PFD1_CLKGATE_SHIFT              15
+#define ANATOP_PFD_480_PFD1_CLKGATE_MASK               (0x3f << ANATOP_PFD_480_PFD1_CLKGATE_SHIFT)
+#define ANATOP_PFD_480_PFD2_FRAC_SHIFT                 16
+#define ANATOP_PFD_480_PFD2_FRAC_MASK                  (1 << ANATOP_PFD_480_PFD2_FRAC_SHIFT)
+#define ANATOP_PFD_480_PFD2_STABLE_SHIFT               22
+#define ANATOP_PFD_480_PFD2_STABLE_MASK                        (1 << ANATOP_PFD_480_PFD2_STABLE_SHIFT)
+#define ANATOP_PFD_480_PFD2_CLKGATE_SHIFT              23
+#define ANATOP_PFD_480_PFD2_CLKGATE_MASK               (0x3f << ANATOP_PFD_480_PFD2_CLKGATE_SHIFT)
+#define ANATOP_PFD_480_PFD3_FRAC_SHIFT                 24
+#define ANATOP_PFD_480_PFD3_FRAC_MASK                  (1 << ANATOP_PFD_480_PFD3_FRAC_SHIFT)
+#define ANATOP_PFD_480_PFD3_STABLE_SHIFT               30
+#define ANATOP_PFD_480_PFD3_STABLE_MASK                        (1 << ANATOP_PFD_480_PFD3_STABLE_SHIFT)
+#define ANATOP_PFD_480_PFD3_CLKGATE_SHIFT              31
+
+#define BM_ANADIG_PLL_ARM_LOCK                         (1 << 31)
+#define BM_ANADIG_PLL_ARM_PLL_SEL                      (1 << 19)
+#define BM_ANADIG_PLL_ARM_LVDS_24MHZ_SEL               (1 << 18)
+#define BM_ANADIG_PLL_ARM_LVDS_SEL                     (1 << 17)
+#define BM_ANADIG_PLL_ARM_BYPASS                       (1 << 16)
+#define BP_ANADIG_PLL_ARM_BYPASS_CLK_SRC               14
+#define BM_ANADIG_PLL_ARM_BYPASS_CLK_SRC               (0x3 << BP_ANADIG_PLL_ARM_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_ARM_BYPASS_CLK_SRC(v)         \
+       (((v) << BP_ANADIG_PLL_ARM_BYPASS_CLK_SRC) & \
+               BM_ANADIG_PLL_ARM_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__OSC_24M      0x0
+#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__ANACLK_1     0x1
+#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__ANACLK_2     0x2
+#define BV_ANADIG_PLL_ARM_BYPASS_CLK_SRC__XOR          0x3
+#define BM_ANADIG_PLL_ARM_ENABLE                       (1 << 13)
+#define BM_ANADIG_PLL_ARM_POWERDOWN                    (1 << 12)
+#define BM_ANADIG_PLL_ARM_HOLD_RING_OFF                        (1 << 11)
+#define BM_ANADIG_PLL_ARM_DOUBLE_CP                    (1 << 10)
+#define BM_ANADIG_PLL_ARM_HALF_CP                      (1 << 9)
+#define BM_ANADIG_PLL_ARM_DOUBLE_LF                    (1 << 8)
+#define BM_ANADIG_PLL_ARM_HALF_LF                      (1 << 7)
+#define BP_ANADIG_PLL_ARM_DIV_SELECT                   0
+#define BM_ANADIG_PLL_ARM_DIV_SELECT                   (0x7F << BP_ANADIG_PLL_ARM_DIV_SELECT)
+#define BF_ANADIG_PLL_ARM_DIV_SELECT(v)                 \
+       (((v) << BP_ANADIG_PLL_ARM_DIV_SELECT) & \
+               BM_ANADIG_PLL_ARM_DIV_SELECT)
+
+#define BM_ANADIG_PLL_528_CTRL_LOCK                    (1 << 31)
+#define BM_ANADIG_PLL_528_PFD_OFFSET_EN                        (1 << 18)
+#define BM_ANADIG_PLL_528_DITHER_ENABLE                        (1 << 17)
+#define BM_ANADIG_PLL_528_CTRL_BYPASS                  (1 << 16)
+#define BP_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC          14
+#define BM_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC          (0x3 << BP_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC(v)         \
+       (((v) << BP_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC) & \
+               BM_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC__OSC_24M 0x0
+#define BV_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC__ANACLK_1        0x1
+#define BV_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC__ANACLK_2        0x2
+#define BV_ANADIG_PLL_528_CTRL_BYPASS_CLK_SRC__XOR     0x3
+#define BM_ANADIG_PLL_528_CTRL_ENABLE                  (1 << 13)
+#define BM_ANADIG_PLL_528_CTRL_POWER                   (1 << 12)
+#define BM_ANADIG_PLL_528_CTRL_HOLD_RING_OFF           (1 << 11)
+#define BM_ANADIG_PLL_528_CTRL_DOUBLE_CP               (1 << 10)
+#define BM_ANADIG_PLL_528_CTRL_HALF_CP                 (1 << 9)
+#define BM_ANADIG_PLL_528_CTRL_DOUBLE_LF               (1 << 8)
+#define BM_ANADIG_PLL_528_CTRL_HALF_LF                 (1 << 7)
+#define BM_ANADIG_PLL_528_CTRL_EN_USB_CLKS             (1 << 6)
+#define BP_ANADIG_PLL_528_CTRL_CONTROL0                        2
+#define BM_ANADIG_PLL_528_CTRL_CONTROL0                        (0x7 << BP_ANADIG_PLL_528_CTRL_CONTROL0)
+#define BF_ANADIG_PLL_528_CTRL_CONTROL0(v)             \
+       (((v) << BP_ANADIG_PLL_528_CTRL_CONTROL0) &     \
+               BM_ANADIG_PLL_528_CTRL_CONTROL0)
+#define BP_ANADIG_PLL_528_CTRL_DIV_SELECT              0
+#define BM_ANADIG_PLL_528_CTRL_DIV_SELECT              (0x3 << BP_ANADIG_PLL_528_CTRL_DIV_SELECT)
+#define BF_ANADIG_PLL_528_CTRL_DIV_SELECT(v)           \
+       (((v) << BP_ANADIG_PLL_528_CTRL_DIV_SELECT) &   \
+               BM_ANADIG_PLL_528_CTRL_DIV_SELECT)
+
+#define BM_ANADIG_PLL_AUDIO_LOCK                       (1 << 31)
+#define BM_ANADIG_PLL_AUDIO_SSC_EN                     (1 << 21)
+#define BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT            19
+#define BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT            (0x3 << BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
+#define BF_ANADIG_PLL_AUDIO_TEST_DIV_SELECT(v)                         \
+       (((v) << BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT) & BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
+#define BM_ANADIG_PLL_AUDIO_PFD_OFFSET_EN              (1 << 18)
+#define BM_ANADIG_PLL_AUDIO_DITHER_ENABLE              (1 << 17)
+#define BM_ANADIG_PLL_AUDIO_BYPASS                     (1 << 16)
+#define BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC             14
+#define BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC             (0x3 << BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC(v)                          \
+       (((v) << BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC) & BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__OSC_24M    0x0
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_1   0x1
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_2   0x2
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__XOR                0x3
+#define BM_ANADIG_PLL_AUDIO_ENABLE                     (1 << 13)
+#define BM_ANADIG_PLL_AUDIO_POWERDOWN                  (1 << 12)
+#define BM_ANADIG_PLL_AUDIO_HOLD_RING_OFF              (1 << 11)
+#define BM_ANADIG_PLL_AUDIO_DOUBLE_CP                  (1 << 10)
+#define BM_ANADIG_PLL_AUDIO_HALF_CP                    (1 << 9)
+#define BM_ANADIG_PLL_AUDIO_DOUBLE_LF                  (1 << 8)
+#define BM_ANADIG_PLL_AUDIO_HALF_LF                    (1 << 7)
+#define BP_ANADIG_PLL_AUDIO_DIV_SELECT                 0
+#define BM_ANADIG_PLL_AUDIO_DIV_SELECT                 (0x7F << BP_ANADIG_PLL_AUDIO_DIV_SELECT)
+#define BF_ANADIG_PLL_AUDIO_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_AUDIO_DIV_SELECT) & \
+               BM_ANADIG_PLL_AUDIO_DIV_SELECT)
+
+#define BP_ANADIG_PLL_AUDIO_NUM_A                      0
+#define BM_ANADIG_PLL_AUDIO_NUM_A                      (0x3FFFFFFF << BP_ANADIG_PLL_AUDIO_NUM_A)
+#define BF_ANADIG_PLL_AUDIO_NUM_A(v)         \
+       (((v) << BP_ANADIG_PLL_AUDIO_NUM_A) & \
+               BM_ANADIG_PLL_AUDIO_NUM_A)
+
+#define BP_ANADIG_PLL_AUDIO_DENOM_B                    0
+#define BM_ANADIG_PLL_AUDIO_DENOM_B                    (0x3FFFFFFF << BP_ANADIG_PLL_AUDIO_DENOM_B)
+#define BF_ANADIG_PLL_AUDIO_DENOM_B(v)         \
+       (((v) << BP_ANADIG_PLL_AUDIO_DENOM_B) & \
+               BM_ANADIG_PLL_AUDIO_DENOM_B)
+
+#define BM_ANADIG_PLL_VIDEO_LOCK                       (1 << 31)
+#define BM_ANADIG_PLL_VIDEO_SSC_EN                     (1 << 21)
+#define BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT            19
+#define BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT            (0x3 << BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT)
+#define BF_ANADIG_PLL_VIDEO_TEST_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_TEST_DIV_SELECT) & \
+               BM_ANADIG_PLL_VIDEO_TEST_DIV_SELECT)
+#define BM_ANADIG_PLL_VIDEO_PFD_OFFSET_EN              (1 << 18)
+#define BM_ANADIG_PLL_VIDEO_DITHER_ENABLE              (1 << 17)
+#define BM_ANADIG_PLL_VIDEO_BYPASS                     (1 << 16)
+#define BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC             14
+#define BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC             (0x3 << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC) & \
+               BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__OSC_24M    0x0
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_1   0x1
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_2   0x2
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__XOR                0x3
+#define BM_ANADIG_PLL_VIDEO_ENABLE                     (1 << 13)
+#define BM_ANADIG_PLL_VIDEO_POWERDOWN                  (1 << 12)
+#define BM_ANADIG_PLL_VIDEO_HOLD_RING_OFF              (1 << 11)
+#define BM_ANADIG_PLL_VIDEO_DOUBLE_CP                  (1 << 10)
+#define BM_ANADIG_PLL_VIDEO_HALF_CP                    (1 << 9)
+#define BM_ANADIG_PLL_VIDEO_DOUBLE_LF                  (1 << 8)
+#define BM_ANADIG_PLL_VIDEO_HALF_LF                    (1 << 7)
+#define BP_ANADIG_PLL_VIDEO_DIV_SELECT                 0
+#define BM_ANADIG_PLL_VIDEO_DIV_SELECT                 (0x7F << BP_ANADIG_PLL_VIDEO_DIV_SELECT)
+#define BF_ANADIG_PLL_VIDEO_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_DIV_SELECT) & \
+               BM_ANADIG_PLL_VIDEO_DIV_SELECT)
+
+#define BP_ANADIG_PLL_VIDEO_NUM_A                      0
+#define BM_ANADIG_PLL_VIDEO_NUM_A                      (0x3FFFFFFF << BP_ANADIG_PLL_VIDEO_NUM_A)
+#define BF_ANADIG_PLL_VIDEO_NUM_A(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_NUM_A) & \
+               BM_ANADIG_PLL_VIDEO_NUM_A)
+
+#define BP_ANADIG_PLL_VIDEO_DENOM_B                    0
+#define BM_ANADIG_PLL_VIDEO_DENOM_B                    (0x3FFFFFFF << BP_ANADIG_PLL_VIDEO_DENOM_B)
+#define BF_ANADIG_PLL_VIDEO_DENOM_B(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_DENOM_B) & \
+               BM_ANADIG_PLL_VIDEO_DENOM_B)
+
+#define BM_ANADIG_PLL_MLB_LOCK                         (1 << 31)
+#define BP_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG          26
+#define BM_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG          (0x7 << BP_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG)
+#define BF_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG(v)         \
+       (((v) << BP_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG) & \
+               BM_ANADIG_PLL_MLB_MLB_FLT_RES_DLY_CFG)
+#define BP_ANADIG_PLL_MLB_RX_CLK_DLY_CFG               23
+#define BM_ANADIG_PLL_MLB_RX_CLK_DLY_CFG               (0x7 << BP_ANADIG_PLL_MLB_RX_CLK_DLY_CFG)
+#define BF_ANADIG_PLL_MLB_RX_CLK_DLY_CFG(v)         \
+       (((v) << BP_ANADIG_PLL_MLB_RX_CLK_DLY_CFG) & \
+               BM_ANADIG_PLL_MLB_RX_CLK_DLY_CFG)
+#define BP_ANADIG_PLL_MLB_VDDD_DLY_CFG                 20
+#define BM_ANADIG_PLL_MLB_VDDD_DLY_CFG                 (0x7 << BP_ANADIG_PLL_MLB_VDDD_DLY_CFG)
+#define BF_ANADIG_PLL_MLB_VDDD_DLY_CFG(v)         \
+       (((v) << BP_ANADIG_PLL_MLB_VDDD_DLY_CFG) & \
+               BM_ANADIG_PLL_MLB_VDDD_DLY_CFG)
+#define BP_ANADIG_PLL_MLB_VDDA_DLY_CFG                 17
+#define BM_ANADIG_PLL_MLB_VDDA_DLY_CFG                 (0x7 << BP_ANADIG_PLL_MLB_VDDA_DLY_CFG)
+#define BF_ANADIG_PLL_MLB_VDDA_DLY_CFG(v)         \
+       (((v) << BP_ANADIG_PLL_MLB_VDDA_DLY_CFG) & \
+               BM_ANADIG_PLL_MLB_VDDA_DLY_CFG)
+#define BM_ANADIG_PLL_MLB_BYPASS                       (1 << 16)
+#define BP_ANADIG_PLL_MLB_PHASE_SEL                    12
+#define BM_ANADIG_PLL_MLB_PHASE_SEL                    (0x7 << BP_ANADIG_PLL_MLB_PHASE_SEL)
+#define BF_ANADIG_PLL_MLB_PHASE_SEL(v)         \
+       (((v) << BP_ANADIG_PLL_MLB_PHASE_SEL) & \
+               BM_ANADIG_PLL_MLB_PHASE_SEL)
+#define BM_ANADIG_PLL_MLB_HOLD_RING_OFF                        (1 << 11)
+
+#define BM_ANADIG_PLL_ENET_LOCK                                (1 << 31)
+#define BM_ANADIG_PLL_ENET_ENABLE_SATA                 (1 << 20)
+#define BM_ANADIG_PLL_ENET_ENABLE_PCIE                 (1 << 19)
+#define BM_ANADIG_PLL_ENET_PFD_OFFSET_EN               (1 << 18)
+#define BM_ANADIG_PLL_ENET_DITHER_ENABLE               (1 << 17)
+#define BM_ANADIG_PLL_ENET_BYPASS                      (1 << 16)
+#define BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC              14
+#define BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC              (0x3 << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_ENET_BYPASS_CLK_SRC(v)         \
+       (((v) << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC) & \
+               BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__OSC_24M     0x0
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_1    0x1
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_2    0x2
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__XOR         0x3
+#define BM_ANADIG_PLL_ENET_ENABLE                      (1 << 13)
+#define BM_ANADIG_PLL_ENET_POWERDOWN                   (1 << 12)
+#define BM_ANADIG_PLL_ENET_HOLD_RING_OFF               (1 << 11)
+#define BM_ANADIG_PLL_ENET_DOUBLE_CP                   (1 << 10)
+#define BM_ANADIG_PLL_ENET_HALF_CP                     (1 << 9)
+#define BM_ANADIG_PLL_ENET_DOUBLE_LF                   (1 << 8)
+#define BM_ANADIG_PLL_ENET_HALF_LF                     (1 << 7)
+#define BP_ANADIG_PLL_ENET_DIV_SELECT                  0
+#define BM_ANADIG_PLL_ENET_DIV_SELECT                  (0x3 << BP_ANADIG_PLL_ENET_DIV_SELECT)
+#define BF_ANADIG_PLL_ENET_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_ENET_DIV_SELECT) & \
+               BM_ANADIG_PLL_ENET_DIV_SELECT)
+
+#define BM_ANADIG_PFD_480_PFD3_CLKGATE                 (1 << 31)
+#define BM_ANADIG_PFD_480_PFD3_STABLE                  (1 << 30)
+#define BP_ANADIG_PFD_480_PFD3_FRAC                    24
+#define BM_ANADIG_PFD_480_PFD3_FRAC                    (0x3F << BP_ANADIG_PFD_480_PFD3_FRAC)
+#define BF_ANADIG_PFD_480_PFD3_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_480_PFD3_FRAC) & \
+               BM_ANADIG_PFD_480_PFD3_FRAC)
+
+#define BP_ANADIG_ANA_MISC0_CLKGATE_DELAY              26
+#define BM_ANADIG_ANA_MISC0_CLKGATE_DELAY              (0x7 << BP_ANADIG_ANA_MISC0_CLKGATE_DELAY)
+#define BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(v)         \
+       (((v) << BP_ANADIG_ANA_MISC0_CLKGATE_DELAY) & \
+               BM_ANADIG_ANA_MISC0_CLKGATE_DELAY)
+#define BM_ANADIG_ANA_MISC0_CLKGATE_CTRL               (1 << 25)
+#define BP_ANADIG_ANA_MISC0_ANAMUX                     21
+#define BM_ANADIG_ANA_MISC0_ANAMUX                     (0xf << BP_ANADIG_ANA_MISC0_ANAMUX)
+#define BF_ANADIG_ANA_MISC0_ANAMUX(v)         \
+       (((v) << BP_ANADIG_ANA_MISC0_ANAMUX) & \
+               BM_ANADIG_ANA_MISC0_ANAMUX)
+#define BM_ANADIG_ANA_MISC0_ANAMUX_EN                  (1 << 20)
+#define BP_ANADIG_ANA_MISC0_WBCP_VPW_THRESH            18
+#define BM_ANADIG_ANA_MISC0_WBCP_VPW_THRESH            (0x3 << BP_ANADIG_ANA_MISC0_WBCP_VPW_THRESH)
+#define BF_ANADIG_ANA_MISC0_WBCP_VPW_THRESH(v)         \
+       (((v) << BP_ANADIG_ANA_MISC0_WBCP_VPW_THRESH) & \
+               BM_ANADIG_ANA_MISC0_WBCP_VPW_THRESH)
+#define BM_ANADIG_ANA_MISC0_OSC_XTALOK_EN              (1 << 17)
+#define BM_ANADIG_ANA_MISC0_OSC_XTALOK                 (1 << 16)
+#define BP_ANADIG_ANA_MISC0_OSC_I                      14
+#define BM_ANADIG_ANA_MISC0_OSC_I                      (0x3 << BP_ANADIG_ANA_MISC0_OSC_I)
+#define BF_ANADIG_ANA_MISC0_OSC_I(v)         \
+       (((v) << BP_ANADIG_ANA_MISC0_OSC_I) & \
+               BM_ANADIG_ANA_MISC0_OSC_I)
+#define BM_ANADIG_ANA_MISC0_RTC_RINGOSC_EN             (1 << 13)
+#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG           (1 << 12)
+#define BP_ANADIG_ANA_MISC0_REFTOP_BIAS_TST            8
+#define BM_ANADIG_ANA_MISC0_REFTOP_BIAS_TST            (0x3 << BP_ANADIG_ANA_MISC0_REFTOP_BIAS_TST)
+#define BF_ANADIG_ANA_MISC0_REFTOP_BIAS_TST(v)         \
+       (((v) << BP_ANADIG_ANA_MISC0_REFTOP_BIAS_TST) & \
+               BM_ANADIG_ANA_MISC0_REFTOP_BIAS_TST)
+#define BM_ANADIG_ANA_MISC0_REFTOP_VBGUP               (1 << 7)
+#define BP_ANADIG_ANA_MISC0_REFTOP_VBGADJ              4
+#define BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ              (0x7 << BP_ANADIG_ANA_MISC0_REFTOP_VBGADJ)
+#define BF_ANADIG_ANA_MISC0_REFTOP_VBGADJ(v)         \
+       (((v) << BP_ANADIG_ANA_MISC0_REFTOP_VBGADJ) & \
+               BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ)
+#define BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF          (1 << 3)
+#define BM_ANADIG_ANA_MISC0_REFTOP_LOWPOWER            (1 << 2)
+#define BM_ANADIG_ANA_MISC0_REFTOP_PWDVBGUP            (1 << 1)
+#define BM_ANADIG_ANA_MISC0_REFTOP_PWD                 (1 << 0)
+
+#define BM_ANADIG_ANA_MISC1_IRQ_DIG_BO                 (1 << 31)
+#define BM_ANADIG_ANA_MISC1_IRQ_ANA_BO                 (1 << 30)
+#define BM_ANADIG_ANA_MISC1_IRQ_TEMPSENSE_BO           (1 << 29)
+#define BM_ANADIG_ANA_MISC1_LVDSCLK2_IBEN              (1 << 13)
+#define BM_ANADIG_ANA_MISC1_LVDSCLK1_IBEN              (1 << 12)
+#define BM_ANADIG_ANA_MISC1_LVDSCLK2_OBEN              (1 << 11)
+#define BM_ANADIG_ANA_MISC1_LVDSCLK1_OBEN              (1 << 10)
+#define BP_ANADIG_ANA_MISC1_LVDS2_CLK_SEL              5
+#define BM_ANADIG_ANA_MISC1_LVDS2_CLK_SEL              (0x1f << BP_ANADIG_ANA_MISC1_LVDS2_CLK_SEL)
+#define BF_ANADIG_ANA_MISC1_LVDS2_CLK_SEL(v)         \
+       (((v) << BP_ANADIG_ANA_MISC1_LVDS2_CLK_SEL) & \
+               BM_ANADIG_ANA_MISC1_LVDS2_CLK_SEL)
+#define BP_ANADIG_ANA_MISC1_LVDS1_CLK_SEL              0
+#define BM_ANADIG_ANA_MISC1_LVDS1_CLK_SEL              (0x1F << BP_ANADIG_ANA_MISC1_LVDS1_CLK_SEL)
+#define BF_ANADIG_ANA_MISC1_LVDS1_CLK_SEL(v)         \
+       (((v) << BP_ANADIG_ANA_MISC1_LVDS1_CLK_SEL) & \
+               BM_ANADIG_ANA_MISC1_LVDS1_CLK_SEL)
+
+#define BP_ANADIG_ANA_MISC2_CONTROL3                   30
+#define BM_ANADIG_ANA_MISC2_CONTROL3                   (0x3 << BP_ANADIG_ANA_MISC2_CONTROL3)
+#define BF_ANADIG_ANA_MISC2_CONTROL3(v)                 \
+       (((v) << BP_ANADIG_ANA_MISC2_CONTROL3) & \
+               BM_ANADIG_ANA_MISC2_CONTROL3)
+#define BP_ANADIG_ANA_MISC2_REG2_STEP_TIME             28
+#define BM_ANADIG_ANA_MISC2_REG2_STEP_TIME             (0x3 << BP_ANADIG_ANA_MISC2_REG2_STEP_TIME)
+#define BF_ANADIG_ANA_MISC2_REG2_STEP_TIME(v)         \
+       (((v) << BP_ANADIG_ANA_MISC2_REG2_STEP_TIME) & \
+               BM_ANADIG_ANA_MISC2_REG2_STEP_TIME)
+#define BP_ANADIG_ANA_MISC2_REG1_STEP_TIME             26
+#define BM_ANADIG_ANA_MISC2_REG1_STEP_TIME             (0x3 << BP_ANADIG_ANA_MISC2_REG1_STEP_TIME)
+#define BF_ANADIG_ANA_MISC2_REG1_STEP_TIME(v)         \
+       (((v) << BP_ANADIG_ANA_MISC2_REG1_STEP_TIME) & \
+               BM_ANADIG_ANA_MISC2_REG1_STEP_TIME)
+#define BP_ANADIG_ANA_MISC2_REG0_STEP_TIME             24
+#define BM_ANADIG_ANA_MISC2_REG0_STEP_TIME             (0x3 << BP_ANADIG_ANA_MISC2_REG0_STEP_TIME)
+#define BF_ANADIG_ANA_MISC2_REG0_STEP_TIME(v)         \
+       (((v) << BP_ANADIG_ANA_MISC2_REG0_STEP_TIME) & \
+               BM_ANADIG_ANA_MISC2_REG0_STEP_TIME)
+#define BM_ANADIG_ANA_MISC2_CONTROL2                   (1 << 23)
+#define BM_ANADIG_ANA_MISC2_REG2_OK                    (1 << 22)
+#define BM_ANADIG_ANA_MISC2_REG2_ENABLE_BO             (1 << 21)
+#define BM_ANADIG_ANA_MISC2_REG2_BO_STATUS             (1 << 19)
+#define BP_ANADIG_ANA_MISC2_REG2_BO_OFFSET             16
+#define BM_ANADIG_ANA_MISC2_REG2_BO_OFFSET             (0x7 << BP_ANADIG_ANA_MISC2_REG2_BO_OFFSET)
+#define BF_ANADIG_ANA_MISC2_REG2_BO_OFFSET(v)         \
+       (((v) << BP_ANADIG_ANA_MISC2_REG2_BO_OFFSET) & \
+               BM_ANADIG_ANA_MISC2_REG2_BO_OFFSET)
+#define BM_ANADIG_ANA_MISC2_CONTROL1                   (1 << 15)
+#define BM_ANADIG_ANA_MISC2_REG1_OK                    (1 << 14)
+#define BM_ANADIG_ANA_MISC2_REG1_ENABLE_BO             (1 << 13)
+#define BM_ANADIG_ANA_MISC2_REG1_BO_STATUS             (1 << 11)
+#define BP_ANADIG_ANA_MISC2_REG1_BO_OFFSET             8
+#define BM_ANADIG_ANA_MISC2_REG1_BO_OFFSET             (0x7 << BP_ANADIG_ANA_MISC2_REG1_BO_OFFSET
+#define BF_ANADIG_ANA_MISC2_REG1_BO_OFFSET(v)         \
+       (((v) << BP_ANADIG_ANA_MISC2_REG1_BO_OFFSET) & \
+               BM_ANADIG_ANA_MISC2_REG1_BO_OFFSET)
+#define BM_ANADIG_ANA_MISC2_CONTROL0                   (1 << 7)
+#define BM_ANADIG_ANA_MISC2_REG0_OK                    (1 << 6)
+#define BM_ANADIG_ANA_MISC2_REG0_ENABLE_BO             (1 << 5)
+#define BM_ANADIG_ANA_MISC2_REG0_BO_STATUS             (1 << 3)
+#define BP_ANADIG_ANA_MISC2_REG0_BO_OFFSET             0
+#define BM_ANADIG_ANA_MISC2_REG0_BO_OFFSET             (0x7 << BP_ANADIG_ANA_MISC2_REG0_BO_OFFSET)
+#define BF_ANADIG_ANA_MISC2_REG0_BO_OFFSET(v)         \
+       (((v) << BP_ANADIG_ANA_MISC2_REG0_BO_OFFSET) & \
+               BM_ANADIG_ANA_MISC2_REG0_BO_OFFSET)
+
+#define BP_ANADIG_TEMPSENSE0_ALARM_VALUE               20
+#define BM_ANADIG_TEMPSENSE0_ALARM_VALUE               (0xFFF << BP_ANADIG_TEMPSENSE0_ALARM_VALUE)
+#define BF_ANADIG_TEMPSENSE0_ALARM_VALUE(v)         \
+       (((v) << BP_ANADIG_TEMPSENSE0_ALARM_VALUE) & \
+               BM_ANADIG_TEMPSENSE0_ALARM_VALUE)
+#define BP_ANADIG_TEMPSENSE0_TEMP_VALUE                        8
+#define BM_ANADIG_TEMPSENSE0_TEMP_VALUE                        (0xFFF << BP_ANADIG_TEMPSENSE0_TEMP_VALUE)
+#define BF_ANADIG_TEMPSENSE0_TEMP_VALUE(v)         \
+       (((v) << BP_ANADIG_TEMPSENSE0_TEMP_VALUE) & \
+               BM_ANADIG_TEMPSENSE0_TEMP_VALUE)
+#define BM_ANADIG_TEMPSENSE0_TEST                      (1 << 6)
+#define BP_ANADIG_TEMPSENSE0_VBGADJ                    3
+#define BM_ANADIG_TEMPSENSE0_VBGADJ                    (0x7 << BP_ANADIG_TEMPSENSE0_VBGADJ)
+#define BF_ANADIG_TEMPSENSE0_VBGADJ(v)         \
+       (((v) << BP_ANADIG_TEMPSENSE0_VBGADJ) & \
+               BM_ANADIG_TEMPSENSE0_VBGADJ)
+#define BM_ANADIG_TEMPSENSE0_FINISHED                  (1 << 2)
+#define BM_ANADIG_TEMPSENSE0_MEASURE_TEMP              (1 << 1)
+#define BM_ANADIG_TEMPSENSE0_POWER_DOWN                        (1 << 0)
+
+#define BP_ANADIG_TEMPSENSE1_MEASURE_FREQ              0
+#define BM_ANADIG_TEMPSENSE1_MEASURE_FREQ              (0xFFFF << BP_ANADIG_TEMPSENSE1_MEASURE_FREQ)
+#define BF_ANADIG_TEMPSENSE1_MEASURE_FREQ(v)         \
+       (((v) << BP_ANADIG_TEMPSENSE1_MEASURE_FREQ) & \
+               BM_ANADIG_TEMPSENSE1_MEASURE_FREQ)
+
+#define MXC_CCM_CCGR6_USBOH3_OFFSET                    0
+#define MXC_CCM_CCGR6_USBOH3_MASK                      (3 << MXC_CCM_CCGR6_USBOH3_OFFSET)
+#define MXC_CCM_CCGR6_USDHC1_OFFSET                    2
+#define MXC_CCM_CCGR6_USDHC1_MASK                      (3 << MXC_CCM_CCGR6_USDHC1_OFFSET)
+#define MXC_CCM_CCGR6_USDHC2_OFFSET                    4
+#define MXC_CCM_CCGR6_USDHC2_MASK                      (3 << MXC_CCM_CCGR6_USDHC2_OFFSET)
+#define MXC_CCM_CCGR6_USDHC3_OFFSET                    6
+#define MXC_CCM_CCGR6_USDHC3_MASK                      (3 << MXC_CCM_CCGR6_USDHC3_OFFSET)
+#define MXC_CCM_CCGR6_USDHC4_OFFSET                    8
+#define MXC_CCM_CCGR6_USDHC4_MASK                      (3 << MXC_CCM_CCGR6_USDHC4_OFFSET)
+#define MXC_CCM_CCGR6_EMI_SLOW_OFFSET                  10
+#define MXC_CCM_CCGR6_EMI_SLOW_MASK                    (3 << MXC_CCM_CCGR6_EMI_SLOW_OFFSET)
 #ifdef CONFIG_MX6SX
-#define MXC_CCM_CCGR6_PWM8_OFFSET              16
-#define MXC_CCM_CCGR6_PWM8_MASK                        (3 << MXC_CCM_CCGR6_PWM8_OFFSET)
-#define MXC_CCM_CCGR6_VADC_OFFSET              20
-#define MXC_CCM_CCGR6_VADC_MASK                        (3 << MXC_CCM_CCGR6_VADC_OFFSET)
-#define MXC_CCM_CCGR6_GIS_OFFSET               22
-#define MXC_CCM_CCGR6_GIS_MASK                 (3 << MXC_CCM_CCGR6_GIS_OFFSET)
-#define MXC_CCM_CCGR6_I2C4_OFFSET              24
-#define MXC_CCM_CCGR6_I2C4_MASK                        (3 << MXC_CCM_CCGR6_I2C4_OFFSET)
-#define MXC_CCM_CCGR6_PWM5_OFFSET              26
-#define MXC_CCM_CCGR6_PWM5_MASK                        (3 << MXC_CCM_CCGR6_PWM5_OFFSET)
-#define MXC_CCM_CCGR6_PWM6_OFFSET              28
-#define MXC_CCM_CCGR6_PWM6_MASK                        (3 << MXC_CCM_CCGR6_PWM6_OFFSET)
-#define MXC_CCM_CCGR6_PWM7_OFFSET              30
-#define MXC_CCM_CCGR6_PWM7_MASK                        (3 << MXC_CCM_CCGR6_PWM7_OFFSET)
+#define MXC_CCM_CCGR6_PWM8_OFFSET                      16
+#define MXC_CCM_CCGR6_PWM8_MASK                                (3 << MXC_CCM_CCGR6_PWM8_OFFSET)
+#define MXC_CCM_CCGR6_VADC_OFFSET                      20
+#define MXC_CCM_CCGR6_VADC_MASK                                (3 << MXC_CCM_CCGR6_VADC_OFFSET)
+#define MXC_CCM_CCGR6_GIS_OFFSET                       22
+#define MXC_CCM_CCGR6_GIS_MASK                         (3 << MXC_CCM_CCGR6_GIS_OFFSET)
+#define MXC_CCM_CCGR6_I2C4_OFFSET                      24
+#define MXC_CCM_CCGR6_I2C4_MASK                                (3 << MXC_CCM_CCGR6_I2C4_OFFSET)
+#define MXC_CCM_CCGR6_PWM5_OFFSET                      26
+#define MXC_CCM_CCGR6_PWM5_MASK                                (3 << MXC_CCM_CCGR6_PWM5_OFFSET)
+#define MXC_CCM_CCGR6_PWM6_OFFSET                      28
+#define MXC_CCM_CCGR6_PWM6_MASK                                (3 << MXC_CCM_CCGR6_PWM6_OFFSET)
+#define MXC_CCM_CCGR6_PWM7_OFFSET                      30
+#define MXC_CCM_CCGR6_PWM7_MASK                                (3 << MXC_CCM_CCGR6_PWM7_OFFSET)
 #else
-#define MXC_CCM_CCGR6_VDOAXICLK_OFFSET         12
-#define MXC_CCM_CCGR6_VDOAXICLK_MASK           (3 << MXC_CCM_CCGR6_VDOAXICLK_OFFSET)
+#define MXC_CCM_CCGR6_VDOAXICLK_OFFSET                 12
+#define MXC_CCM_CCGR6_VDOAXICLK_MASK                   (3 << MXC_CCM_CCGR6_VDOAXICLK_OFFSET)
 #endif
 
-#define BM_ANADIG_PLL_SYS_LOCK 0x80000000
-#define BP_ANADIG_PLL_SYS_RSVD0      20
-#define BM_ANADIG_PLL_SYS_RSVD0 0x7FF00000
-#define BF_ANADIG_PLL_SYS_RSVD0(v)  \
-       (((v) << 20) & BM_ANADIG_PLL_SYS_RSVD0)
-#define BM_ANADIG_PLL_SYS_PLL_SEL 0x00080000
-#define BM_ANADIG_PLL_SYS_LVDS_24MHZ_SEL 0x00040000
-#define BM_ANADIG_PLL_SYS_LVDS_SEL 0x00020000
-#define BM_ANADIG_PLL_SYS_BYPASS 0x00010000
-#define BP_ANADIG_PLL_SYS_BYPASS_CLK_SRC      14
-#define BM_ANADIG_PLL_SYS_BYPASS_CLK_SRC 0x0000C000
-#define BF_ANADIG_PLL_SYS_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_SYS_BYPASS_CLK_SRC)
-#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__OSC_24M  0x0
-#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__ANACLK_1 0x1
-#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__ANACLK_2 0x2
-#define BV_ANADIG_PLL_SYS_BYPASS_CLK_SRC__XOR      0x3
-#define BM_ANADIG_PLL_SYS_ENABLE 0x00002000
-#define BM_ANADIG_PLL_SYS_POWERDOWN 0x00001000
-#define BM_ANADIG_PLL_SYS_HOLD_RING_OFF 0x00000800
-#define BM_ANADIG_PLL_SYS_DOUBLE_CP 0x00000400
-#define BM_ANADIG_PLL_SYS_HALF_CP 0x00000200
-#define BM_ANADIG_PLL_SYS_DOUBLE_LF 0x00000100
-#define BM_ANADIG_PLL_SYS_HALF_LF 0x00000080
-#define BP_ANADIG_PLL_SYS_DIV_SELECT      0
-#define BM_ANADIG_PLL_SYS_DIV_SELECT 0x0000007F
-#define BF_ANADIG_PLL_SYS_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_SYS_DIV_SELECT)
-
-#define BM_ANADIG_USB1_PLL_480_CTRL_LOCK 0x80000000
-#define BP_ANADIG_USB1_PLL_480_CTRL_RSVD1      17
-#define BM_ANADIG_USB1_PLL_480_CTRL_RSVD1 0x7FFE0000
-#define BF_ANADIG_USB1_PLL_480_CTRL_RSVD1(v)  \
-       (((v) << 17) & BM_ANADIG_USB1_PLL_480_CTRL_RSVD1)
-#define BM_ANADIG_USB1_PLL_480_CTRL_BYPASS 0x00010000
-#define BP_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC      14
-#define BM_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC 0x0000C000
-#define BF_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC)
-#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__OSC_24M  0x0
-#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_1 0x1
-#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_2 0x2
-#define BV_ANADIG_USB1_PLL_480_CTRL_BYPASS_CLK_SRC__XOR      0x3
-#define BM_ANADIG_USB1_PLL_480_CTRL_ENABLE 0x00002000
-#define BM_ANADIG_USB1_PLL_480_CTRL_POWER 0x00001000
-#define BM_ANADIG_USB1_PLL_480_CTRL_HOLD_RING_OFF 0x00000800
-#define BM_ANADIG_USB1_PLL_480_CTRL_DOUBLE_CP 0x00000400
-#define BM_ANADIG_USB1_PLL_480_CTRL_HALF_CP 0x00000200
-#define BM_ANADIG_USB1_PLL_480_CTRL_DOUBLE_LF 0x00000100
-#define BM_ANADIG_USB1_PLL_480_CTRL_HALF_LF 0x00000080
-#define BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS 0x00000040
-#define BM_ANADIG_USB1_PLL_480_CTRL_RSVD0 0x00000020
-#define BP_ANADIG_USB1_PLL_480_CTRL_CONTROL0      2
-#define BM_ANADIG_USB1_PLL_480_CTRL_CONTROL0 0x0000001C
-#define BF_ANADIG_USB1_PLL_480_CTRL_CONTROL0(v)  \
-       (((v) << 2) & BM_ANADIG_USB1_PLL_480_CTRL_CONTROL0)
-#define BP_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT      0
-#define BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT 0x00000003
-#define BF_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT)
-
-#define BM_ANADIG_PLL_528_LOCK 0x80000000
-#define BP_ANADIG_PLL_528_RSVD1      19
-#define BM_ANADIG_PLL_528_RSVD1 0x7FF80000
-#define BF_ANADIG_PLL_528_RSVD1(v)  \
-       (((v) << 19) & BM_ANADIG_PLL_528_RSVD1)
-#define BM_ANADIG_PLL_528_PFD_OFFSET_EN 0x00040000
-#define BM_ANADIG_PLL_528_DITHER_ENABLE 0x00020000
-#define BM_ANADIG_PLL_528_BYPASS 0x00010000
-#define BP_ANADIG_PLL_528_BYPASS_CLK_SRC      14
-#define BM_ANADIG_PLL_528_BYPASS_CLK_SRC 0x0000C000
-#define BF_ANADIG_PLL_528_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_528_BYPASS_CLK_SRC)
-#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__OSC_24M  0x0
-#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_1 0x1
-#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_2 0x2
-#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__XOR      0x3
-#define BM_ANADIG_PLL_528_ENABLE 0x00002000
-#define BM_ANADIG_PLL_528_POWERDOWN 0x00001000
-#define BM_ANADIG_PLL_528_HOLD_RING_OFF 0x00000800
-#define BM_ANADIG_PLL_528_DOUBLE_CP 0x00000400
-#define BM_ANADIG_PLL_528_HALF_CP 0x00000200
-#define BM_ANADIG_PLL_528_DOUBLE_LF 0x00000100
-#define BM_ANADIG_PLL_528_HALF_LF 0x00000080
-#define BP_ANADIG_PLL_528_RSVD0      1
-#define BM_ANADIG_PLL_528_RSVD0 0x0000007E
-#define BF_ANADIG_PLL_528_RSVD0(v)  \
-       (((v) << 1) & BM_ANADIG_PLL_528_RSVD0)
-#define BM_ANADIG_PLL_528_DIV_SELECT 0x00000001
-
-#define BP_ANADIG_PLL_528_SS_STOP      16
-#define BM_ANADIG_PLL_528_SS_STOP 0xFFFF0000
-#define BF_ANADIG_PLL_528_SS_STOP(v) \
-       (((v) << 16) & BM_ANADIG_PLL_528_SS_STOP)
-#define BM_ANADIG_PLL_528_SS_ENABLE 0x00008000
-#define BP_ANADIG_PLL_528_SS_STEP      0
-#define BM_ANADIG_PLL_528_SS_STEP 0x00007FFF
-#define BF_ANADIG_PLL_528_SS_STEP(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_528_SS_STEP)
-
-#define BP_ANADIG_PLL_528_NUM_RSVD0      30
-#define BM_ANADIG_PLL_528_NUM_RSVD0 0xC0000000
-#define BF_ANADIG_PLL_528_NUM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_528_NUM_RSVD0)
-#define BP_ANADIG_PLL_528_NUM_A      0
-#define BM_ANADIG_PLL_528_NUM_A 0x3FFFFFFF
-#define BF_ANADIG_PLL_528_NUM_A(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_528_NUM_A)
-
-#define BP_ANADIG_PLL_528_DENOM_RSVD0      30
-#define BM_ANADIG_PLL_528_DENOM_RSVD0 0xC0000000
-#define BF_ANADIG_PLL_528_DENOM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_528_DENOM_RSVD0)
-#define BP_ANADIG_PLL_528_DENOM_B      0
-#define BM_ANADIG_PLL_528_DENOM_B 0x3FFFFFFF
-#define BF_ANADIG_PLL_528_DENOM_B(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_528_DENOM_B)
-
-#define BM_ANADIG_PLL_AUDIO_LOCK 0x80000000
-#define BP_ANADIG_PLL_AUDIO_RSVD0      22
-#define BM_ANADIG_PLL_AUDIO_RSVD0 0x7FC00000
-#define BF_ANADIG_PLL_AUDIO_RSVD0(v)  \
-       (((v) << 22) & BM_ANADIG_PLL_AUDIO_RSVD0)
-#define BM_ANADIG_PLL_AUDIO_SSC_EN 0x00200000
-#define BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT      19
-#define BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT 0x00180000
-#define BF_ANADIG_PLL_AUDIO_TEST_DIV_SELECT(v)  \
-       (((v) << 19) & BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
-#define BM_ANADIG_PLL_AUDIO_PFD_OFFSET_EN 0x00040000
-#define BM_ANADIG_PLL_AUDIO_DITHER_ENABLE 0x00020000
-#define BM_ANADIG_PLL_AUDIO_BYPASS 0x00010000
-#define BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC      14
-#define BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC 0x0000C000
-#define BF_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
-#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__OSC_24M  0x0
-#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_1 0x1
-#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_2 0x2
-#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__XOR      0x3
-#define BM_ANADIG_PLL_AUDIO_ENABLE 0x00002000
-#define BM_ANADIG_PLL_AUDIO_POWERDOWN 0x00001000
-#define BM_ANADIG_PLL_AUDIO_HOLD_RING_OFF 0x00000800
-#define BM_ANADIG_PLL_AUDIO_DOUBLE_CP 0x00000400
-#define BM_ANADIG_PLL_AUDIO_HALF_CP 0x00000200
-#define BM_ANADIG_PLL_AUDIO_DOUBLE_LF 0x00000100
-#define BM_ANADIG_PLL_AUDIO_HALF_LF 0x00000080
-#define BP_ANADIG_PLL_AUDIO_DIV_SELECT      0
-#define BM_ANADIG_PLL_AUDIO_DIV_SELECT 0x0000007F
-#define BF_ANADIG_PLL_AUDIO_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_AUDIO_DIV_SELECT)
-
-#define BP_ANADIG_PLL_AUDIO_NUM_RSVD0      30
-#define BM_ANADIG_PLL_AUDIO_NUM_RSVD0 0xC0000000
-#define BF_ANADIG_PLL_AUDIO_NUM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_AUDIO_NUM_RSVD0)
-#define BP_ANADIG_PLL_AUDIO_NUM_A      0
-#define BM_ANADIG_PLL_AUDIO_NUM_A 0x3FFFFFFF
-#define BF_ANADIG_PLL_AUDIO_NUM_A(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_AUDIO_NUM_A)
-
-#define BP_ANADIG_PLL_AUDIO_DENOM_RSVD0      30
-#define BM_ANADIG_PLL_AUDIO_DENOM_RSVD0 0xC0000000
-#define BF_ANADIG_PLL_AUDIO_DENOM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_AUDIO_DENOM_RSVD0)
-#define BP_ANADIG_PLL_AUDIO_DENOM_B      0
-#define BM_ANADIG_PLL_AUDIO_DENOM_B 0x3FFFFFFF
-#define BF_ANADIG_PLL_AUDIO_DENOM_B(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_AUDIO_DENOM_B)
-
-#define BM_ANADIG_PLL_VIDEO_LOCK 0x80000000
-#define BP_ANADIG_PLL_VIDEO_RSVD0      22
-#define BM_ANADIG_PLL_VIDEO_RSVD0 0x7FC00000
-#define BF_ANADIG_PLL_VIDEO_RSVD0(v)  \
-       (((v) << 22) & BM_ANADIG_PLL_VIDEO_RSVD0)
-#define BM_ANADIG_PLL_VIDEO_SSC_EN 0x00200000
-#define BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT      19
-#define BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT 0x00180000
-#define BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(v)  \
-       (((v) << 19) & BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT)
-#define BM_ANADIG_PLL_VIDEO_PFD_OFFSET_EN 0x00040000
-#define BM_ANADIG_PLL_VIDEO_DITHER_ENABLE 0x00020000
-#define BM_ANADIG_PLL_VIDEO_BYPASS 0x00010000
-#define BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC      14
-#define BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC 0x0000C000
-#define BF_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
-#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__OSC_24M  0x0
-#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_1 0x1
-#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_2 0x2
-#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__XOR      0x3
-#define BM_ANADIG_PLL_VIDEO_ENABLE 0x00002000
-#define BM_ANADIG_PLL_VIDEO_POWERDOWN 0x00001000
-#define BM_ANADIG_PLL_VIDEO_HOLD_RING_OFF 0x00000800
-#define BM_ANADIG_PLL_VIDEO_DOUBLE_CP 0x00000400
-#define BM_ANADIG_PLL_VIDEO_HALF_CP 0x00000200
-#define BM_ANADIG_PLL_VIDEO_DOUBLE_LF 0x00000100
-#define BM_ANADIG_PLL_VIDEO_HALF_LF 0x00000080
-#define BP_ANADIG_PLL_VIDEO_DIV_SELECT      0
-#define BM_ANADIG_PLL_VIDEO_DIV_SELECT 0x0000007F
-#define BF_ANADIG_PLL_VIDEO_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_VIDEO_DIV_SELECT)
-
-#define BP_ANADIG_PLL_VIDEO_NUM_RSVD0      30
-#define BM_ANADIG_PLL_VIDEO_NUM_RSVD0 0xC0000000
-#define BF_ANADIG_PLL_VIDEO_NUM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_VIDEO_NUM_RSVD0)
-#define BP_ANADIG_PLL_VIDEO_NUM_A      0
-#define BM_ANADIG_PLL_VIDEO_NUM_A 0x3FFFFFFF
-#define BF_ANADIG_PLL_VIDEO_NUM_A(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_VIDEO_NUM_A)
-
-#define BP_ANADIG_PLL_VIDEO_DENOM_RSVD0      30
-#define BM_ANADIG_PLL_VIDEO_DENOM_RSVD0 0xC0000000
-#define BF_ANADIG_PLL_VIDEO_DENOM_RSVD0(v) \
-       (((v) << 30) & BM_ANADIG_PLL_VIDEO_DENOM_RSVD0)
-#define BP_ANADIG_PLL_VIDEO_DENOM_B      0
-#define BM_ANADIG_PLL_VIDEO_DENOM_B 0x3FFFFFFF
-#define BF_ANADIG_PLL_VIDEO_DENOM_B(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_VIDEO_DENOM_B)
-
-#define BM_ANADIG_PLL_ENET_LOCK 0x80000000
-#define BP_ANADIG_PLL_ENET_RSVD1      21
-#define BM_ANADIG_PLL_ENET_RSVD1 0x7FE00000
-#define BF_ANADIG_PLL_ENET_RSVD1(v)  \
-       (((v) << 21) & BM_ANADIG_PLL_ENET_RSVD1)
-#define BM_ANADIG_PLL_ENET_REF_25M_ENABLE 0x00200000
-#define BM_ANADIG_PLL_ENET_ENABLE_SATA 0x00100000
-#define BM_ANADIG_PLL_ENET_ENABLE_PCIE 0x00080000
-#define BM_ANADIG_PLL_ENET_PFD_OFFSET_EN 0x00040000
-#define BM_ANADIG_PLL_ENET_DITHER_ENABLE 0x00020000
-#define BM_ANADIG_PLL_ENET_BYPASS 0x00010000
-#define BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC      14
-#define BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC 0x0000C000
-#define BF_ANADIG_PLL_ENET_BYPASS_CLK_SRC(v)  \
-       (((v) << 14) & BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
-#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__OSC_24M  0x0
-#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_1 0x1
-#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_2 0x2
-#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__XOR      0x3
-#define BM_ANADIG_PLL_ENET_ENABLE 0x00002000
-#define BM_ANADIG_PLL_ENET_POWERDOWN 0x00001000
-#define BM_ANADIG_PLL_ENET_HOLD_RING_OFF 0x00000800
-#define BM_ANADIG_PLL_ENET_DOUBLE_CP 0x00000400
-#define BM_ANADIG_PLL_ENET_HALF_CP 0x00000200
-#define BM_ANADIG_PLL_ENET_DOUBLE_LF 0x00000100
-#define BM_ANADIG_PLL_ENET_HALF_LF 0x00000080
-#define BP_ANADIG_PLL_ENET_RSVD0      2
-#define BM_ANADIG_PLL_ENET_RSVD0 0x0000007C
-#define BF_ANADIG_PLL_ENET_RSVD0(v)  \
-       (((v) << 2) & BM_ANADIG_PLL_ENET_RSVD0)
-#define BP_ANADIG_PLL_ENET_DIV_SELECT      0
-#define BM_ANADIG_PLL_ENET_DIV_SELECT 0x00000003
-#define BF_ANADIG_PLL_ENET_DIV_SELECT(v)  \
-       (((v) << 0) & BM_ANADIG_PLL_ENET_DIV_SELECT)
-
-#define BM_ANADIG_PFD_480_PFD3_CLKGATE 0x80000000
-#define BM_ANADIG_PFD_480_PFD3_STABLE 0x40000000
-#define BP_ANADIG_PFD_480_PFD3_FRAC      24
-#define BM_ANADIG_PFD_480_PFD3_FRAC 0x3F000000
-#define BF_ANADIG_PFD_480_PFD3_FRAC(v)  \
-       (((v) << 24) & BM_ANADIG_PFD_480_PFD3_FRAC)
-#define BM_ANADIG_PFD_480_PFD2_CLKGATE 0x00800000
-#define BM_ANADIG_PFD_480_PFD2_STABLE 0x00400000
-#define BP_ANADIG_PFD_480_PFD2_FRAC      16
-#define BM_ANADIG_PFD_480_PFD2_FRAC 0x003F0000
-#define BF_ANADIG_PFD_480_PFD2_FRAC(v)  \
-       (((v) << 16) & BM_ANADIG_PFD_480_PFD2_FRAC)
-#define BM_ANADIG_PFD_480_PFD1_CLKGATE 0x00008000
-#define BM_ANADIG_PFD_480_PFD1_STABLE 0x00004000
-#define BP_ANADIG_PFD_480_PFD1_FRAC      8
-#define BM_ANADIG_PFD_480_PFD1_FRAC 0x00003F00
-#define BF_ANADIG_PFD_480_PFD1_FRAC(v)  \
-       (((v) << 8) & BM_ANADIG_PFD_480_PFD1_FRAC)
-#define BM_ANADIG_PFD_480_PFD0_CLKGATE 0x00000080
-#define BM_ANADIG_PFD_480_PFD0_STABLE 0x00000040
-#define BP_ANADIG_PFD_480_PFD0_FRAC      0
-#define BM_ANADIG_PFD_480_PFD0_FRAC 0x0000003F
-#define BF_ANADIG_PFD_480_PFD0_FRAC(v)  \
-       (((v) << 0) & BM_ANADIG_PFD_480_PFD0_FRAC)
-
-#define BM_ANADIG_PFD_528_PFD3_CLKGATE 0x80000000
-#define BM_ANADIG_PFD_528_PFD3_STABLE 0x40000000
-#define BP_ANADIG_PFD_528_PFD3_FRAC      24
-#define BM_ANADIG_PFD_528_PFD3_FRAC 0x3F000000
-#define BF_ANADIG_PFD_528_PFD3_FRAC(v)  \
-       (((v) << 24) & BM_ANADIG_PFD_528_PFD3_FRAC)
-#define BM_ANADIG_PFD_528_PFD2_CLKGATE 0x00800000
-#define BM_ANADIG_PFD_528_PFD2_STABLE 0x00400000
-#define BP_ANADIG_PFD_528_PFD2_FRAC      16
-#define BM_ANADIG_PFD_528_PFD2_FRAC 0x003F0000
-#define BF_ANADIG_PFD_528_PFD2_FRAC(v)  \
-       (((v) << 16) & BM_ANADIG_PFD_528_PFD2_FRAC)
-#define BM_ANADIG_PFD_528_PFD1_CLKGATE 0x00008000
-#define BM_ANADIG_PFD_528_PFD1_STABLE 0x00004000
-#define BP_ANADIG_PFD_528_PFD1_FRAC      8
-#define BM_ANADIG_PFD_528_PFD1_FRAC 0x00003F00
-#define BF_ANADIG_PFD_528_PFD1_FRAC(v)  \
-       (((v) << 8) & BM_ANADIG_PFD_528_PFD1_FRAC)
-#define BM_ANADIG_PFD_528_PFD0_CLKGATE 0x00000080
-#define BM_ANADIG_PFD_528_PFD0_STABLE 0x00000040
-#define BP_ANADIG_PFD_528_PFD0_FRAC      0
-#define BM_ANADIG_PFD_528_PFD0_FRAC 0x0000003F
-#define BF_ANADIG_PFD_528_PFD0_FRAC(v)  \
-       (((v) << 0) & BM_ANADIG_PFD_528_PFD0_FRAC)
+#define BM_ANADIG_USB_PLL_480_CTRL_LOCK                (1 << 31)
+#define BM_ANADIG_USB_PLL_480_CTRL_BYPASS              (1 << 16)
+#define BP_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC      14
+#define BM_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC      (0x3 << BP_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC)
+#define BF_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC(v)          \
+       (((v) << BP_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC) & \
+               BM_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC)
+#define BV_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC__OSC_24M     0x0
+#define BV_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_1    0x1
+#define BV_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC__ANACLK_2    0x2
+#define BV_ANADIG_USB_PLL_480_CTRL_BYPASS_CLK_SRC__XOR         0x3
+#define BM_ANADIG_USB_PLL_480_CTRL_ENABLE              (1 << 13)
+#define BM_ANADIG_USB_PLL_480_CTRL_POWER               (1 << 12)
+#define BM_ANADIG_USB_PLL_480_CTRL_HOLD_RING_OFF       (1 << 11)
+#define BM_ANADIG_USB_PLL_480_CTRL_DOUBLE_CP           (1 << 10)
+#define BM_ANADIG_USB_PLL_480_CTRL_HALF_CP             (1 << 9)
+#define BM_ANADIG_USB_PLL_480_CTRL_DOUBLE_LF           (1 << 8)
+#define BM_ANADIG_USB_PLL_480_CTRL_HALF_LF             (1 << 7)
+#define BM_ANADIG_USB_PLL_480_CTRL_EN_USB_CLKS         (1 << 6)
+#define BP_ANADIG_USB_PLL_480_CTRL_CONTROL0            2
+#define BM_ANADIG_USB_PLL_480_CTRL_CONTROL0            (0x7 << BP_ANADIG_USB_PLL_480_CTRL_CONTROL0)
+#define BF_ANADIG_USB_PLL_480_CTRL_CONTROL0(v)          \
+       (((v) << BP_ANADIG_USB_PLL_480_CTRL_CONTROL0) & \
+               BM_ANADIG_USB_PLL_480_CTRL_CONTROL0)
+#define BP_ANADIG_USB_PLL_480_CTRL_DIV_SELECT          0
+#define BM_ANADIG_USB_PLL_480_CTRL_DIV_SELECT          (0x3 << BP_ANADIG_USB_PLL_480_CTRL_DIV_SELECT)
+#define BF_ANADIG_USB_PLL_480_CTRL_DIV_SELECT(v)          \
+       (((v) << BP_ANADIG_USB_PLL_480_CTRL_DIV_SELECT) & \
+               BM_ANADIG_USB_PLL_480_CTRL_DIV_SELECT)
+
+#define BM_ANADIG_PLL_528_LOCK                         (1 << 31)
+#define BM_ANADIG_PLL_528_PLL_SEL                      (1 << 19)
+#define BM_ANADIG_PLL_528_LVDS_24MHZ_SEL               (1 << 18)
+#define BM_ANADIG_PLL_528_LVDS_SEL                     (1 << 17)
+#define BM_ANADIG_PLL_528_BYPASS                       (1 << 16)
+#define BP_ANADIG_PLL_528_BYPASS_CLK_SRC               14
+#define BM_ANADIG_PLL_528_BYPASS_CLK_SRC               (0x3 << BP_ANADIG_PLL_528_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_528_BYPASS_CLK_SRC(v)         \
+       (((v) << BP_ANADIG_PLL_528_BYPASS_CLK_SRC) & \
+               BM_ANADIG_PLL_528_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__OSC_24M      0x0
+#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_1     0x1
+#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__ANACLK_2     0x2
+#define BV_ANADIG_PLL_528_BYPASS_CLK_SRC__XOR          0x3
+#define BM_ANADIG_PLL_528_ENABLE                       (1 << 13)
+#define BM_ANADIG_PLL_528_POWERDOWN                    (1 << 12)
+#define BM_ANADIG_PLL_528_HOLD_RING_OFF                        (1 << 11)
+#define BM_ANADIG_PLL_528_DOUBLE_CP                    (1 << 10)
+#define BM_ANADIG_PLL_528_HALF_CP                      (1 << 9)
+#define BM_ANADIG_PLL_528_DOUBLE_LF                    (1 << 8)
+#define BM_ANADIG_PLL_528_HALF_LF                      (1 << 7)
+#define BP_ANADIG_PLL_528_DIV_SELECT                   0
+#define BM_ANADIG_PLL_528_DIV_SELECT                   (0x7F << BP_ANADIG_PLL_528_DIV_SELECT)
+#define BF_ANADIG_PLL_528_DIV_SELECT(v)                 \
+       (((v) << BP_ANADIG_PLL_528_DIV_SELECT) & \
+               BM_ANADIG_PLL_528_DIV_SELECT)
+
+#define BP_ANADIG_PLL_528_SS_STOP                      16
+#define BM_ANADIG_PLL_528_SS_STOP                      (0xFFFF << BP_ANADIG_PLL_528_SS_STOP)
+#define BF_ANADIG_PLL_528_SS_STOP(v)         \
+       (((v) << BP_ANADIG_PLL_528_SS_STOP) & \
+               BM_ANADIG_PLL_528_SS_STOP)
+#define BM_ANADIG_PLL_528_SS_ENABLE                    (1 << 15)
+#define BP_ANADIG_PLL_528_SS_STEP                      0
+#define BM_ANADIG_PLL_528_SS_STEP                      (0x7FFF << BP_ANADIG_PLL_528_SS_STEP)
+#define BF_ANADIG_PLL_528_SS_STEP(v)         \
+       (((v) << BP_ANADIG_PLL_528_SS_STEP) & \
+               BM_ANADIG_PLL_528_SS_STEP)
+
+#define BP_ANADIG_PLL_528_NUM_A                                0
+#define BM_ANADIG_PLL_528_NUM_A                                (0x3FFFFFFF << BP_ANADIG_PLL_528_NUM_A)
+#define BF_ANADIG_PLL_528_NUM_A(v)         \
+       (((v) << BP_ANADIG_PLL_528_NUM_A) & \
+               BM_ANADIG_PLL_528_NUM_A)
+
+#define BP_ANADIG_PLL_528_DENOM_B                      0
+#define BM_ANADIG_PLL_528_DENOM_B                      (0x3FFFFFFF << BP_ANADIG_PLL_528_DENOM_B)
+#define BF_ANADIG_PLL_528_DENOM_B(v)         \
+       (((v) << BP_ANADIG_PLL_528_DENOM_B) & \
+               BM_ANADIG_PLL_528_DENOM_B)
+
+#define BM_ANADIG_PLL_AUDIO_LOCK                       (1 << 31)
+#define BM_ANADIG_PLL_AUDIO_SSC_EN                     (1 << 21)
+#define BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT            19
+#define BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT            (0x3 << BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
+#define BF_ANADIG_PLL_AUDIO_TEST_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT) & \
+               BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT)
+#define BM_ANADIG_PLL_AUDIO_PFD_OFFSET_EN              (1 << 18)
+#define BM_ANADIG_PLL_AUDIO_DITHER_ENABLE              (1 << 17)
+#define BM_ANADIG_PLL_AUDIO_BYPASS                     (1 << 16)
+#define BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC             14
+#define BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC             (0x3 << BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC(v)         \
+       (((v) << BP_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC) & \
+               BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__OSC_24M    0x0
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_1   0x1
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__ANACLK_2   0x2
+#define BV_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC__XOR                0x3
+#define BM_ANADIG_PLL_AUDIO_ENABLE                     (1 << 13)
+#define BM_ANADIG_PLL_AUDIO_POWERDOWN                  (1 << 12)
+#define BM_ANADIG_PLL_AUDIO_HOLD_RING_OFF              (1 << 11)
+#define BM_ANADIG_PLL_AUDIO_DOUBLE_CP                  (1 << 10)
+#define BM_ANADIG_PLL_AUDIO_HALF_CP                    (1 << 9)
+#define BM_ANADIG_PLL_AUDIO_DOUBLE_LF                  (1 << 8)
+#define BM_ANADIG_PLL_AUDIO_HALF_LF                    (1 << 7)
+#define BP_ANADIG_PLL_AUDIO_DIV_SELECT                 0
+#define BM_ANADIG_PLL_AUDIO_DIV_SELECT                 (0x7F << BP_ANADIG_PLL_AUDIO_DIV_SELECT)
+#define BF_ANADIG_PLL_AUDIO_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_AUDIO_DIV_SELECT) & \
+               BM_ANADIG_PLL_AUDIO_DIV_SELECT)
+
+#define BP_ANADIG_PLL_AUDIO_NUM_A                      0
+#define BM_ANADIG_PLL_AUDIO_NUM_A                      (0x3FFFFFFF << BP_ANADIG_PLL_AUDIO_NUM_A)
+#define BF_ANADIG_PLL_AUDIO_NUM_A(v)         \
+       (((v) << BP_ANADIG_PLL_AUDIO_NUM_A) & \
+               BM_ANADIG_PLL_AUDIO_NUM_A)
+
+#define BP_ANADIG_PLL_AUDIO_DENOM_B                    0
+#define BM_ANADIG_PLL_AUDIO_DENOM_B                    (0x3FFFFFFF << BP_ANADIG_PLL_AUDIO_DENOM_B)
+#define BF_ANADIG_PLL_AUDIO_DENOM_B(v)         \
+       (((v) << BP_ANADIG_PLL_AUDIO_DENOM_B) & \
+               BM_ANADIG_PLL_AUDIO_DENOM_B)
+
+#define BM_ANADIG_PLL_VIDEO_LOCK                       (1 << 31)
+#define BM_ANADIG_PLL_VIDEO_SSC_EN                     (1 << 21)
+#define BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT            19
+#define BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT            (0x3 << BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT)
+#define BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT) & \
+               BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT)
+#define BM_ANADIG_PLL_VIDEO_PFD_OFFSET_EN              (1 << 18)
+#define BM_ANADIG_PLL_VIDEO_DITHER_ENABLE              (1 << 17)
+#define BM_ANADIG_PLL_VIDEO_BYPASS                     (1 << 16)
+#define BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC             14
+#define BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC             (0x3 << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC) & \
+               BM_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__OSC_24M    0x0
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_1   0x1
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__ANACLK_2   0x2
+#define BV_ANADIG_PLL_VIDEO_BYPASS_CLK_SRC__XOR                0x3
+#define BM_ANADIG_PLL_VIDEO_ENABLE                     (1 << 13)
+#define BM_ANADIG_PLL_VIDEO_POWERDOWN                  (1 << 12)
+#define BM_ANADIG_PLL_VIDEO_HOLD_RING_OFF              (1 << 11)
+#define BM_ANADIG_PLL_VIDEO_DOUBLE_CP                  (1 << 10)
+#define BM_ANADIG_PLL_VIDEO_HALF_CP                    (1 << 9)
+#define BM_ANADIG_PLL_VIDEO_DOUBLE_LF                  (1 << 8)
+#define BM_ANADIG_PLL_VIDEO_HALF_LF                    (1 << 7)
+#define BP_ANADIG_PLL_VIDEO_DIV_SELECT                 0
+#define BM_ANADIG_PLL_VIDEO_DIV_SELECT                 (0x7F << BP_ANADIG_PLL_VIDEO_DIV_SELECT)
+#define BF_ANADIG_PLL_VIDEO_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_DIV_SELECT) & \
+               BM_ANADIG_PLL_VIDEO_DIV_SELECT)
+
+#define BP_ANADIG_PLL_VIDEO_NUM_A                      0
+#define BM_ANADIG_PLL_VIDEO_NUM_A                      (0x3FFFFFFF << BP_ANADIG_PLL_VIDEO_NUM_A)
+#define BF_ANADIG_PLL_VIDEO_NUM_A(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_NUM_A) & \
+               BM_ANADIG_PLL_VIDEO_NUM_A)
+
+#define BP_ANADIG_PLL_VIDEO_DENOM_B                    0
+#define BM_ANADIG_PLL_VIDEO_DENOM_B                    (0x3FFFFFFF << BP_ANADIG_PLL_VIDEO_DENOM_B)
+#define BF_ANADIG_PLL_VIDEO_DENOM_B(v)         \
+       (((v) << BP_ANADIG_PLL_VIDEO_DENOM_B) & \
+               BM_ANADIG_PLL_VIDEO_DENOM_B)
+
+#define BM_ANADIG_PLL_ENET_LOCK                                (1 << 31)
+#define BM_ANADIG_PLL_ENET_REF_25M_ENABLE              (1 << 21)
+#define BM_ANADIG_PLL_ENET_ENABLE_SATA                 (1 << 20)
+#define BM_ANADIG_PLL_ENET_ENABLE_PCIE                 (1 << 19)
+#define BM_ANADIG_PLL_ENET_PFD_OFFSET_EN               (1 << 18)
+#define BM_ANADIG_PLL_ENET_DITHER_ENABLE               (1 << 17)
+#define BM_ANADIG_PLL_ENET_BYPASS                      (1 << 16)
+#define BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC              14
+#define BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC              (0x3 << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
+#define BF_ANADIG_PLL_ENET_BYPASS_CLK_SRC(v)         \
+       (((v) << BP_ANADIG_PLL_ENET_BYPASS_CLK_SRC) & \
+               BM_ANADIG_PLL_ENET_BYPASS_CLK_SRC)
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__OSC_24M     0x0
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_1    0x1
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__ANACLK_2    0x2
+#define BV_ANADIG_PLL_ENET_BYPASS_CLK_SRC__XOR         0x3
+#define BM_ANADIG_PLL_ENET_ENABLE                      (1 << 13)
+#define BM_ANADIG_PLL_ENET_POWERDOWN                   (1 << 12)
+#define BM_ANADIG_PLL_ENET_HOLD_RING_OFF               (1 << 11)
+#define BM_ANADIG_PLL_ENET_DOUBLE_CP                   (1 << 10)
+#define BM_ANADIG_PLL_ENET_HALF_CP                     (1 << 9)
+#define BM_ANADIG_PLL_ENET_DOUBLE_LF                   (1 << 8)
+#define BM_ANADIG_PLL_ENET_HALF_LF                     (1 << 7)
+#define BP_ANADIG_PLL_ENET_DIV_SELECT                  0
+#define BM_ANADIG_PLL_ENET_DIV_SELECT                  (0x3 << BP_ANADIG_PLL_ENET_DIV_SELECT)
+#define BF_ANADIG_PLL_ENET_DIV_SELECT(v)         \
+       (((v) << BP_ANADIG_PLL_ENET_DIV_SELECT) & \
+               BM_ANADIG_PLL_ENET_DIV_SELECT)
+
+#define BM_ANADIG_PFD_480_PFD3_CLKGATE                 (1 << 31)
+#define BM_ANADIG_PFD_480_PFD3_STABLE                  (1 << 30)
+#define BP_ANADIG_PFD_480_PFD3_FRAC                    24
+#define BM_ANADIG_PFD_480_PFD3_FRAC                    (0x3F << BP_ANADIG_PFD_480_PFD3_FRAC)
+#define BF_ANADIG_PFD_480_PFD3_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_480_PFD3_FRAC) & \
+               BM_ANADIG_PFD_480_PFD3_FRAC)
+#define BM_ANADIG_PFD_480_PFD2_CLKGATE                 (1 << 23)
+#define BM_ANADIG_PFD_480_PFD2_STABLE                  (1 << 22)
+#define BP_ANADIG_PFD_480_PFD2_FRAC                    16
+#define BM_ANADIG_PFD_480_PFD2_FRAC                    (0x3F << BP_ANADIG_PFD_480_PFD2_FRAC)
+#define BF_ANADIG_PFD_480_PFD2_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_480_PFD2_FRAC) & \
+               BM_ANADIG_PFD_480_PFD2_FRAC)
+#define BM_ANADIG_PFD_480_PFD1_CLKGATE                 (1 << 15)
+#define BM_ANADIG_PFD_480_PFD1_STABLE                  (1 << 14)
+#define BP_ANADIG_PFD_480_PFD1_FRAC                    8
+#define BM_ANADIG_PFD_480_PFD1_FRAC                    (0x3F << BP_ANADIG_PFD_480_PFD1_FRAC)
+#define BF_ANADIG_PFD_480_PFD1_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_480_PFD1_FRAC) & \
+               BM_ANADIG_PFD_480_PFD1_FRAC)
+#define BM_ANADIG_PFD_480_PFD0_CLKGATE                 (1 << 7)
+#define BM_ANADIG_PFD_480_PFD0_STABLE                  (1 << 6)
+#define BP_ANADIG_PFD_480_PFD0_FRAC                    0
+#define BM_ANADIG_PFD_480_PFD0_FRAC                    (0x3F << BP_ANADIG_PFD_480_PFD0_FRAC)
+#define BF_ANADIG_PFD_480_PFD0_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_480_PFD0_FRAC) & \
+               BM_ANADIG_PFD_480_PFD0_FRAC)
+
+#define BM_ANADIG_PFD_528_PFD3_CLKGATE                 (1 << 31)
+#define BM_ANADIG_PFD_528_PFD3_STABLE                  (1 << 30)
+#define BP_ANADIG_PFD_528_PFD3_FRAC                    24
+#define BM_ANADIG_PFD_528_PFD3_FRAC                    (0x3F << BP_ANADIG_PFD_528_PFD3_FRAC)
+#define BF_ANADIG_PFD_528_PFD3_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_528_PFD3_FRAC) & \
+               BM_ANADIG_PFD_528_PFD3_FRAC)
+#define BM_ANADIG_PFD_528_PFD2_CLKGATE                 (1 << 23)
+#define BM_ANADIG_PFD_528_PFD2_STABLE                  (1 << 22)
+#define BP_ANADIG_PFD_528_PFD2_FRAC                    16
+#define BM_ANADIG_PFD_528_PFD2_FRAC                    (0x3F << BP_ANADIG_PFD_528_PFD2_FRAC)
+#define BF_ANADIG_PFD_528_PFD2_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_528_PFD2_FRAC) & \
+               BM_ANADIG_PFD_528_PFD2_FRAC)
+#define BM_ANADIG_PFD_528_PFD1_CLKGATE                 (1 << 15)
+#define BM_ANADIG_PFD_528_PFD1_STABLE                  (1 << 14)
+#define BP_ANADIG_PFD_528_PFD1_FRAC                    8
+#define BM_ANADIG_PFD_528_PFD1_FRAC                    (0x3F << BP_ANADIG_PFD_528_PFD1_FRAC)
+#define BF_ANADIG_PFD_528_PFD1_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_528_PFD1_FRAC) & \
+               BM_ANADIG_PFD_528_PFD1_FRAC)
+#define BM_ANADIG_PFD_528_PFD0_CLKGATE                 (1 << 7)
+#define BM_ANADIG_PFD_528_PFD0_STABLE                  (1 << 6)
+#define BP_ANADIG_PFD_528_PFD0_FRAC                    0
+#define BM_ANADIG_PFD_528_PFD0_FRAC                    (0x3F << BP_ANADIG_PFD_528_PFD0_FRAC)
+#define BF_ANADIG_PFD_528_PFD0_FRAC(v)         \
+       (((v) << BP_ANADIG_PFD_528_PFD0_FRAC) & \
+               BM_ANADIG_PFD_528_PFD0_FRAC)
 
 #endif /*__ARCH_ARM_MACH_MX6_CCM_REGS_H__ */
index c968600b770f397972722e655221a0f834d49d6c..7368572cbc9f2b8116a2f9d0398b6d63e48dc26b 100644 (file)
@@ -7,44 +7,46 @@
 #ifndef __ASM_ARCH_MX6_IMX_REGS_H__
 #define __ASM_ARCH_MX6_IMX_REGS_H__
 
+#include <asm/imx-common/regs-common.h>
+
 #define ARCH_MXC
 
-#define CONFIG_SYS_CACHELINE_SIZE      32
+#define CONFIG_SYS_CACHELINE_SIZE       64
 
-#define ROMCP_ARB_BASE_ADDR             0x00000000
-#define ROMCP_ARB_END_ADDR              0x000FFFFF
+#define ROMCP_ARB_BASE_ADDR            0x00000000
+#define ROMCP_ARB_END_ADDR             0x000FFFFF
 
 #ifdef CONFIG_MX6SL
-#define GPU_2D_ARB_BASE_ADDR            0x02200000
-#define GPU_2D_ARB_END_ADDR             0x02203FFF
-#define OPENVG_ARB_BASE_ADDR            0x02204000
-#define OPENVG_ARB_END_ADDR             0x02207FFF
-#elif CONFIG_MX6SX
-#define CAAM_ARB_BASE_ADDR              0x00100000
-#define CAAM_ARB_END_ADDR               0x00107FFF
-#define GPU_ARB_BASE_ADDR               0x01800000
-#define GPU_ARB_END_ADDR                0x01803FFF
-#define APBH_DMA_ARB_BASE_ADDR          0x01804000
-#define APBH_DMA_ARB_END_ADDR           0x0180BFFF
-#define M4_BOOTROM_BASE_ADDR                   0x007F8000
+#define GPU_2D_ARB_BASE_ADDR           0x02200000
+#define GPU_2D_ARB_END_ADDR            0x02203FFF
+#define OPENVG_ARB_BASE_ADDR           0x02204000
+#define OPENVG_ARB_END_ADDR            0x02207FFF
+#elif defined(CONFIG_MX6SX)
+#define CAAM_ARB_BASE_ADDR             0x00100000
+#define CAAM_ARB_END_ADDR              0x00107FFF
+#define GPU_ARB_BASE_ADDR              0x01800000
+#define GPU_ARB_END_ADDR               0x01803FFF
+#define APBH_DMA_ARB_BASE_ADDR         0x01804000
+#define APBH_DMA_ARB_END_ADDR          0x0180BFFF
+#define M4_BOOTROM_BASE_ADDR           0x007F8000
 
 #define MXS_APBH_BASE                  APBH_DMA_ARB_BASE_ADDR
 #define MXS_GPMI_BASE                  (APBH_DMA_ARB_BASE_ADDR + 0x02000)
 #define MXS_BCH_BASE                   (APBH_DMA_ARB_BASE_ADDR + 0x04000)
 
 #else
-#define CAAM_ARB_BASE_ADDR              0x00100000
-#define CAAM_ARB_END_ADDR               0x00103FFF
-#define APBH_DMA_ARB_BASE_ADDR          0x00110000
-#define APBH_DMA_ARB_END_ADDR           0x00117FFF
-#define HDMI_ARB_BASE_ADDR              0x00120000
-#define HDMI_ARB_END_ADDR               0x00128FFF
-#define GPU_3D_ARB_BASE_ADDR            0x00130000
-#define GPU_3D_ARB_END_ADDR             0x00133FFF
-#define GPU_2D_ARB_BASE_ADDR            0x00134000
-#define GPU_2D_ARB_END_ADDR             0x00137FFF
-#define DTCP_ARB_BASE_ADDR              0x00138000
-#define DTCP_ARB_END_ADDR               0x0013BFFF
+#define CAAM_ARB_BASE_ADDR             0x00100000
+#define CAAM_ARB_END_ADDR              0x00103FFF
+#define APBH_DMA_ARB_BASE_ADDR         0x00110000
+#define APBH_DMA_ARB_END_ADDR          0x00117FFF
+#define HDMI_ARB_BASE_ADDR             0x00120000
+#define HDMI_ARB_END_ADDR              0x00128FFF
+#define GPU_3D_ARB_BASE_ADDR           0x00130000
+#define GPU_3D_ARB_END_ADDR            0x00133FFF
+#define GPU_2D_ARB_BASE_ADDR           0x00134000
+#define GPU_2D_ARB_END_ADDR            0x00137FFF
+#define DTCP_ARB_BASE_ADDR             0x00138000
+#define DTCP_ARB_END_ADDR              0x0013BFFF
 #endif /* CONFIG_MX6SL */
 
 #define MXS_APBH_BASE                  APBH_DMA_ARB_BASE_ADDR
@@ -53,7 +55,7 @@
 
 /* GPV - PL301 configuration ports */
 #if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
-#define GPV2_BASE_ADDR                  0x00D00000
+#define GPV2_BASE_ADDR                 0x00D00000
 #else
 #define GPV2_BASE_ADDR                 0x00200000
 #endif
 #define GPV4_BASE_ADDR                 0x00F00000
 #define GPV5_BASE_ADDR                 0x01000000
 #define GPV6_BASE_ADDR                 0x01100000
-#define PCIE_ARB_BASE_ADDR              0x08000000
-#define PCIE_ARB_END_ADDR               0x08FFFFFF
+#define PCIE_ARB_BASE_ADDR             0x08000000
+#define PCIE_ARB_END_ADDR              0x08FFFFFF
 
 #else
 #define GPV3_BASE_ADDR                 0x00300000
 #define GPV4_BASE_ADDR                 0x00800000
-#define PCIE_ARB_BASE_ADDR              0x01000000
-#define PCIE_ARB_END_ADDR               0x01FFFFFF
+#define PCIE_ARB_BASE_ADDR             0x01000000
+#define PCIE_ARB_END_ADDR              0x01FFFFFF
 #endif
 
 #define IRAM_BASE_ADDR                 0x00900000
-#define SCU_BASE_ADDR                   0x00A00000
-#define IC_INTERFACES_BASE_ADDR         0x00A00100
-#define GLOBAL_TIMER_BASE_ADDR          0x00A00200
-#define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
-#define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
+#define SCU_BASE_ADDR                  0x00A00000
+#define IC_INTERFACES_BASE_ADDR                0x00A00100
+#define GLOBAL_TIMER_BASE_ADDR         0x00A00200
+#define PRIVATE_TIMERS_WD_BASE_ADDR    0x00A00600
+#define IC_DISTRIBUTOR_BASE_ADDR       0x00A01000
 #define L2_PL310_BASE                  0x00A02000
-#define GPV0_BASE_ADDR                  0x00B00000
-#define GPV1_BASE_ADDR                  0x00C00000
+#define GPV0_BASE_ADDR                 0x00B00000
+#define GPV1_BASE_ADDR                 0x00C00000
 
-#define AIPS1_ARB_BASE_ADDR             0x02000000
-#define AIPS1_ARB_END_ADDR              0x020FFFFF
-#define AIPS2_ARB_BASE_ADDR             0x02100000
-#define AIPS2_ARB_END_ADDR              0x021FFFFF
+#define AIPS1_ARB_BASE_ADDR            0x02000000
+#define AIPS1_ARB_END_ADDR             0x020FFFFF
+#define AIPS2_ARB_BASE_ADDR            0x02100000
+#define AIPS2_ARB_END_ADDR             0x021FFFFF
 #ifdef CONFIG_MX6SX
 #define AIPS3_BASE_ADDR                        0x02200000
 #define AIPS3_END_ADDR                 0x022FFFFF
-#define WEIM_ARB_BASE_ADDR              0x50000000
-#define WEIM_ARB_END_ADDR               0x57FFFFFF
-#define QSPI0_AMBA_BASE                0x60000000
-#define QSPI0_AMBA_END                 0x6FFFFFFF
-#define QSPI1_AMBA_BASE                0x70000000
-#define QSPI1_AMBA_END                 0x7FFFFFFF
+#define WEIM_ARB_BASE_ADDR             0x50000000
+#define WEIM_ARB_END_ADDR              0x57FFFFFF
+#define QSPI0_AMBA_BASE                        0x60000000
+#define QSPI0_AMBA_END                 0x6FFFFFFF
+#define QSPI1_AMBA_BASE                        0x70000000
+#define QSPI1_AMBA_END                 0x7FFFFFFF
 #else
-#define SATA_ARB_BASE_ADDR              0x02200000
-#define SATA_ARB_END_ADDR               0x02203FFF
-#define OPENVG_ARB_BASE_ADDR            0x02204000
-#define OPENVG_ARB_END_ADDR             0x02207FFF
-#define HSI_ARB_BASE_ADDR               0x02208000
-#define HSI_ARB_END_ADDR                0x0220BFFF
-#define IPU1_ARB_BASE_ADDR              0x02400000
-#define IPU1_ARB_END_ADDR               0x027FFFFF
-#define IPU2_ARB_BASE_ADDR              0x02800000
-#define IPU2_ARB_END_ADDR               0x02BFFFFF
-#define WEIM_ARB_BASE_ADDR              0x08000000
-#define WEIM_ARB_END_ADDR               0x0FFFFFFF
+#define SATA_ARB_BASE_ADDR             0x02200000
+#define SATA_ARB_END_ADDR              0x02203FFF
+#define OPENVG_ARB_BASE_ADDR           0x02204000
+#define OPENVG_ARB_END_ADDR            0x02207FFF
+#define HSI_ARB_BASE_ADDR              0x02208000
+#define HSI_ARB_END_ADDR               0x0220BFFF
+#define IPU1_ARB_BASE_ADDR             0x02400000
+#define IPU1_ARB_END_ADDR              0x027FFFFF
+#define IPU2_ARB_BASE_ADDR             0x02800000
+#define IPU2_ARB_END_ADDR              0x02BFFFFF
+#define WEIM_ARB_BASE_ADDR             0x08000000
+#define WEIM_ARB_END_ADDR              0x0FFFFFFF
 #endif
 
 #if (defined(CONFIG_MX6SL) || defined(CONFIG_MX6SX))
-#define MMDC0_ARB_BASE_ADDR             0x80000000
-#define MMDC0_ARB_END_ADDR              0xFFFFFFFF
-#define MMDC1_ARB_BASE_ADDR             0xC0000000
-#define MMDC1_ARB_END_ADDR              0xFFFFFFFF
+#define MMDC0_ARB_BASE_ADDR            0x80000000
+#define MMDC0_ARB_END_ADDR             0xFFFFFFFF
+#define MMDC1_ARB_BASE_ADDR            0xC0000000
+#define MMDC1_ARB_END_ADDR             0xFFFFFFFF
 #else
-#define MMDC0_ARB_BASE_ADDR             0x10000000
-#define MMDC0_ARB_END_ADDR              0x7FFFFFFF
-#define MMDC1_ARB_BASE_ADDR             0x80000000
-#define MMDC1_ARB_END_ADDR              0xFFFFFFFF
+#define MMDC0_ARB_BASE_ADDR            0x10000000
+#define MMDC0_ARB_END_ADDR             0x7FFFFFFF
+#define MMDC1_ARB_BASE_ADDR            0x80000000
+#define MMDC1_ARB_END_ADDR             0xFFFFFFFF
 #endif
 
 #ifndef CONFIG_MX6SX
 #endif
 
 /* Defines for Blocks connected via AIPS (SkyBlue) */
-#define ATZ1_BASE_ADDR              AIPS1_ARB_BASE_ADDR
-#define ATZ2_BASE_ADDR              AIPS2_ARB_BASE_ADDR
-#define AIPS1_BASE_ADDR             AIPS1_ON_BASE_ADDR
-#define AIPS2_BASE_ADDR             AIPS2_ON_BASE_ADDR
-
-#define SPDIF_BASE_ADDR             (ATZ1_BASE_ADDR + 0x04000)
-#define ECSPI1_BASE_ADDR            (ATZ1_BASE_ADDR + 0x08000)
-#define ECSPI2_BASE_ADDR            (ATZ1_BASE_ADDR + 0x0C000)
-#define ECSPI3_BASE_ADDR            (ATZ1_BASE_ADDR + 0x10000)
-#define ECSPI4_BASE_ADDR            (ATZ1_BASE_ADDR + 0x14000)
+#define ATZ1_BASE_ADDR             AIPS1_ARB_BASE_ADDR
+#define ATZ2_BASE_ADDR             AIPS2_ARB_BASE_ADDR
+#define AIPS1_BASE_ADDR                    AIPS1_ON_BASE_ADDR
+#define AIPS2_BASE_ADDR                    AIPS2_ON_BASE_ADDR
+
+#define SPDIF_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x04000)
+#define ECSPI1_BASE_ADDR           (ATZ1_BASE_ADDR + 0x08000)
+#define ECSPI2_BASE_ADDR           (ATZ1_BASE_ADDR + 0x0C000)
+#define ECSPI3_BASE_ADDR           (ATZ1_BASE_ADDR + 0x10000)
+#define ECSPI4_BASE_ADDR           (ATZ1_BASE_ADDR + 0x14000)
 #ifdef CONFIG_MX6SL
-#define UART5_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x18000)
-#define UART1_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x20000)
-#define UART2_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x24000)
-#define SSI1_IPS_BASE_ADDR          (ATZ1_BASE_ADDR + 0x28000)
-#define SSI2_IPS_BASE_ADDR          (ATZ1_BASE_ADDR + 0x2C000)
-#define SSI3_IPS_BASE_ADDR          (ATZ1_BASE_ADDR + 0x30000)
-#define UART3_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x34000)
-#define UART4_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x38000)
+#define UART5_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x18000)
+#define UART1_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x20000)
+#define UART2_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x24000)
+#define SSI1_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x28000)
+#define SSI2_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x2C000)
+#define SSI3_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x30000)
+#define UART3_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x34000)
+#define UART4_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x38000)
 #else
 #ifndef CONFIG_MX6SX
-#define ECSPI5_BASE_ADDR            (ATZ1_BASE_ADDR + 0x18000)
+#define ECSPI5_BASE_ADDR           (ATZ1_BASE_ADDR + 0x18000)
 #endif
-#define UART1_BASE                  (ATZ1_BASE_ADDR + 0x20000)
-#define ESAI1_BASE_ADDR             (ATZ1_BASE_ADDR + 0x24000)
-#define SSI1_BASE_ADDR              (ATZ1_BASE_ADDR + 0x28000)
-#define SSI2_BASE_ADDR              (ATZ1_BASE_ADDR + 0x2C000)
-#define SSI3_BASE_ADDR              (ATZ1_BASE_ADDR + 0x30000)
-#define ASRC_BASE_ADDR              (ATZ1_BASE_ADDR + 0x34000)
+#define UART1_BASE                 (ATZ1_BASE_ADDR + 0x20000)
+#define ESAI1_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x24000)
+#define SSI1_BASE_ADDR             (ATZ1_BASE_ADDR + 0x28000)
+#define SSI2_BASE_ADDR             (ATZ1_BASE_ADDR + 0x2C000)
+#define SSI3_BASE_ADDR             (ATZ1_BASE_ADDR + 0x30000)
+#define ASRC_BASE_ADDR             (ATZ1_BASE_ADDR + 0x34000)
 #endif
 
 #ifndef CONFIG_MX6SX
-#define SPBA_BASE_ADDR              (ATZ1_BASE_ADDR + 0x3C000)
-#define VPU_BASE_ADDR               (ATZ1_BASE_ADDR + 0x40000)
+#define SPBA_BASE_ADDR             (ATZ1_BASE_ADDR + 0x3C000)
+#define VPU_BASE_ADDR              (ATZ1_BASE_ADDR + 0x40000)
 #endif
-#define AIPS1_ON_BASE_ADDR          (ATZ1_BASE_ADDR + 0x7C000)
-
-#define AIPS1_OFF_BASE_ADDR         (ATZ1_BASE_ADDR + 0x80000)
-#define PWM1_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x0000)
-#define PWM2_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x4000)
-#define PWM3_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x8000)
-#define PWM4_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0xC000)
-#define CAN1_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x10000)
-#define CAN2_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x14000)
-#define GPT1_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x18000)
-#define GPIO1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x1C000)
-#define GPIO2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x20000)
-#define GPIO3_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x24000)
-#define GPIO4_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x28000)
-#define GPIO5_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x2C000)
-#define GPIO6_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x30000)
-#define GPIO7_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x34000)
-#define KPP_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x38000)
-#define WDOG1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x3C000)
-#define WDOG2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x40000)
-#define ANATOP_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x48000)
-#define USB_PHY0_BASE_ADDR          (AIPS1_OFF_BASE_ADDR + 0x49000)
-#define USB_PHY1_BASE_ADDR          (AIPS1_OFF_BASE_ADDR + 0x4a000)
-#define CCM_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x44000)
-#define SNVS_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x4C000)
-#define EPIT1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x50000)
-#define EPIT2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x54000)
-#define SRC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x58000)
-#define GPC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x5C000)
-#define IOMUXC_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x60000)
+#define AIPS1_ON_BASE_ADDR         (ATZ1_BASE_ADDR + 0x7C000)
+
+#define AIPS1_OFF_BASE_ADDR        (ATZ1_BASE_ADDR + 0x80000)
+#define PWM1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x0000)
+#define PWM2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x4000)
+#define PWM3_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x8000)
+#define PWM4_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0xC000)
+#define CAN1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x10000)
+#define CAN2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x14000)
+#define GPT1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x18000)
+#define GPIO1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x1C000)
+#define GPIO2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x20000)
+#define GPIO3_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x24000)
+#define GPIO4_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x28000)
+#define GPIO5_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x2C000)
+#define GPIO6_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x30000)
+#define GPIO7_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x34000)
+#define KPP_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x38000)
+#define WDOG1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x3C000)
+#define WDOG2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x40000)
+#define CCM_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x44000)
+#define ANATOP_BASE_ADDR           (AIPS1_OFF_BASE_ADDR + 0x48000)
+#define USB_PHY0_BASE_ADDR         (AIPS1_OFF_BASE_ADDR + 0x49000)
+#define USB_PHY1_BASE_ADDR         (AIPS1_OFF_BASE_ADDR + 0x4a000)
+#define SNVS_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x4C000)
+#define EPIT1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x50000)
+#define EPIT2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x54000)
+#define SRC_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x58000)
+#define GPC_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x5C000)
+#define IOMUXC_BASE_ADDR           (AIPS1_OFF_BASE_ADDR + 0x60000)
 #ifdef CONFIG_MX6SL
-#define CSI_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x64000)
-#define SIPIX_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define CSI_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x64000)
+#define SIPIX_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x68000)
 #define SDMA_PORT_HOST_BASE_ADDR    (AIPS1_OFF_BASE_ADDR + 0x6C000)
-#elif CONFIG_MX6SX
+#elif defined(CONFIG_MX6SX)
 #define CANFD1_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x68000)
 #define SDMA_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x6C000)
 #define CANFD2_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x70000)
 #define SEMAPHORE2_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x78000)
 #define RDC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x7C000)
 #else
-#define DCIC1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x64000)
-#define DCIC2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define DCIC1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x64000)
+#define DCIC2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x68000)
 #define DMA_REQ_PORT_HOST_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
 #endif
 
-#define AIPS2_ON_BASE_ADDR          (ATZ2_BASE_ADDR + 0x7C000)
-#define AIPS2_OFF_BASE_ADDR         (ATZ2_BASE_ADDR + 0x80000)
-#define CAAM_BASE_ADDR              (ATZ2_BASE_ADDR)
+#define AIPS2_ON_BASE_ADDR         (ATZ2_BASE_ADDR + 0x7C000)
+#define AIPS2_OFF_BASE_ADDR        (ATZ2_BASE_ADDR + 0x80000)
+#define CAAM_BASE_ADDR             (ATZ2_BASE_ADDR)
 #define ARM_BASE_ADDR              (ATZ2_BASE_ADDR + 0x40000)
-#define USB_PL301_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x0000)
-#define USB_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x4000)
+#define USB_PL301_BASE_ADDR        (AIPS2_OFF_BASE_ADDR + 0x0000)
+#define USB_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x4000)
 
-#define ENET_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x8000)
+#define ENET_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x8000)
 #ifdef CONFIG_MX6SL
-#define MSHC_IPS_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0xC000)
+#define MSHC_IPS_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0xC000)
 #else
-#define MLB_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0xC000)
+#define MLB_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0xC000)
 #endif
 
-#define USDHC1_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x10000)
-#define USDHC2_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x14000)
-#define USDHC3_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x18000)
-#define USDHC4_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x1C000)
-#define I2C1_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x20000)
-#define I2C2_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x24000)
-#define I2C3_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x28000)
-#define ROMCP_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x2C000)
-#define MMDC_P0_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x30000)
+#define USDHC1_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x10000)
+#define USDHC2_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x14000)
+#define USDHC3_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x18000)
+#define USDHC4_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x1C000)
+#define I2C1_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x20000)
+#define I2C2_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x24000)
+#define I2C3_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x28000)
+#define ROMCP_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x2C000)
+#define MMDC_P0_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x30000)
 #ifdef CONFIG_MX6SL
-#define RNGB_IPS_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x34000)
-#elif CONFIG_MX6SX
-#define ENET2_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x34000)
+#define RNGB_IPS_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x34000)
+#elif defined(CONFIG_MX6SX)
+#define ENET2_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x34000)
 #else
-#define MMDC_P1_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x34000)
+#define MMDC_P1_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x34000)
 #endif
 
-#define WEIM_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x38000)
-#define OCOTP_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x3C000)
-#define CSU_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x40000)
+#define WEIM_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x38000)
+#define OCOTP_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x3C000)
+#define CSU_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x40000)
 #define IP2APB_PERFMON1_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x44000)
 #define IP2APB_PERFMON2_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x48000)
 #ifdef CONFIG_MX6SX
 #else
 #define IP2APB_PERFMON3_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x4C000)
 #endif
-#define IP2APB_TZASC1_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x50000)
+#define IP2APB_TZASC1_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x50000)
 #ifdef CONFIG_MX6SX
-#define SAI1_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x54000)
+#define SAI1_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x54000)
 #else
-#define IP2APB_TZASC2_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x54000)
+#define IP2APB_TZASC2_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x54000)
 #endif
-#define AUDMUX_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x58000)
-#define AUDMUX_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x58000)
+#define AUDMUX_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x58000)
 #ifdef CONFIG_MX6SX
-#define SAI2_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x5C000)
-#define QSPI0_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x60000)
-#define QSPI1_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x64000)
+#define SAI2_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x5C000)
+#define QSPI0_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x60000)
+#define QSPI1_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x64000)
 #else
-#define MIPI_CSI2_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x5C000)
-#define MIPI_DSI_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x60000)
-#define VDOA_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x64000)
+#define MIPI_CSI2_BASE_ADDR        (AIPS2_OFF_BASE_ADDR + 0x5C000)
+#define MIPI_DSI_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x60000)
+#define VDOA_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x64000)
 #endif
-#define UART2_BASE                  (AIPS2_OFF_BASE_ADDR + 0x68000)
-#define UART3_BASE                  (AIPS2_OFF_BASE_ADDR + 0x6C000)
-#define UART4_BASE                  (AIPS2_OFF_BASE_ADDR + 0x70000)
-#define UART5_BASE                  (AIPS2_OFF_BASE_ADDR + 0x74000)
+#define UART2_BASE                 (AIPS2_OFF_BASE_ADDR + 0x68000)
+#define UART3_BASE                 (AIPS2_OFF_BASE_ADDR + 0x6C000)
+#define UART4_BASE                 (AIPS2_OFF_BASE_ADDR + 0x70000)
+#define UART5_BASE                 (AIPS2_OFF_BASE_ADDR + 0x74000)
 #define IP2APB_USBPHY1_BASE_ADDR    (AIPS2_OFF_BASE_ADDR + 0x78000)
 #define IP2APB_USBPHY2_BASE_ADDR    (AIPS2_OFF_BASE_ADDR + 0x7C000)
 
 #ifdef CONFIG_MX6SX
-#define GIS_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x04000)
-#define DCIC1_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x0C000)
-#define DCIC2_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x10000)
-#define CSI1_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x14000)
-#define PXP_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x18000)
-#define CSI2_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x1C000)
-#define LCDIF1_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x20000)
-#define LCDIF2_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x24000)
-#define VADC_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x28000)
-#define VDEC_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x2C000)
-#define SPBA_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x3C000)
-#define AIPS3_CONFIG_BASE_ADDR      (AIPS3_ARB_BASE_ADDR + 0x7C000)
-#define ADC1_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x80000)
-#define ADC2_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x84000)
-#define WDOG3_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x88000)
-#define ECSPI5_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x8C000)
-#define HS_BASE_ADDR                (AIPS3_ARB_BASE_ADDR + 0x90000)
-#define MU_MCU_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x94000)
-#define CANFD_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x98000)
-#define MU_DSP_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x9C000)
-#define UART6_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xA0000)
-#define PWM5_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xA4000)
-#define PWM6_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xA8000)
-#define PWM7_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xAC000)
-#define PWM8_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xB0000)
+#define GIS_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x04000)
+#define DCIC1_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x0C000)
+#define DCIC2_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x10000)
+#define CSI1_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x14000)
+#define PXP_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x18000)
+#define CSI2_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x1C000)
+#define LCDIF1_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x20000)
+#define LCDIF2_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x24000)
+#define VADC_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x28000)
+#define VDEC_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x2C000)
+#define SPBA_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x3C000)
+#define AIPS3_CONFIG_BASE_ADDR     (AIPS3_ARB_BASE_ADDR + 0x7C000)
+#define ADC1_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x80000)
+#define ADC2_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x84000)
+#define WDOG3_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x88000)
+#define ECSPI5_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x8C000)
+#define HS_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x90000)
+#define MU_MCU_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x94000)
+#define CANFD_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x98000)
+#define MU_DSP_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x9C000)
+#define UART6_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0xA0000)
+#define PWM5_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xA4000)
+#define PWM6_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xA8000)
+#define PWM7_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xAC000)
+#define PWM8_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xB0000)
 #endif
 
-#define CHIP_REV_1_0                 0x10
-#define CHIP_REV_1_2                 0x12
-#define CHIP_REV_1_5                 0x15
+#define CHIP_REV_1_0                0x10
+#define CHIP_REV_1_2                0x12
+#define CHIP_REV_1_5                0x15
 #ifndef CONFIG_MX6SX
-#define IRAM_SIZE                    0x00040000
+#define IRAM_SIZE                   0x00040000
 #else
-#define IRAM_SIZE                    0x00020000
+#define IRAM_SIZE                   0x00020000
 #endif
+#define IMX_IIM_BASE                OCOTP_BASE_ADDR
 #define FEC_QUIRK_ENET_MAC
 
 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
 #include <asm/types.h>
 
-extern void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
-
-#define SRC_SCR_CORE_1_RESET_OFFSET     14
-#define SRC_SCR_CORE_1_RESET_MASK       (1<<SRC_SCR_CORE_1_RESET_OFFSET)
-#define SRC_SCR_CORE_2_RESET_OFFSET     15
-#define SRC_SCR_CORE_2_RESET_MASK       (1<<SRC_SCR_CORE_2_RESET_OFFSET)
-#define SRC_SCR_CORE_3_RESET_OFFSET     16
-#define SRC_SCR_CORE_3_RESET_MASK       (1<<SRC_SCR_CORE_3_RESET_OFFSET)
-#define SRC_SCR_CORE_1_ENABLE_OFFSET    22
-#define SRC_SCR_CORE_1_ENABLE_MASK      (1<<SRC_SCR_CORE_1_ENABLE_OFFSET)
-#define SRC_SCR_CORE_2_ENABLE_OFFSET    23
-#define SRC_SCR_CORE_2_ENABLE_MASK      (1<<SRC_SCR_CORE_2_ENABLE_OFFSET)
-#define SRC_SCR_CORE_3_ENABLE_OFFSET    24
-#define SRC_SCR_CORE_3_ENABLE_MASK      (1<<SRC_SCR_CORE_3_ENABLE_OFFSET)
+#define SRC_SCR_CORE_1_RESET_OFFSET    14
+#define SRC_SCR_CORE_1_RESET_MASK      (1 << SRC_SCR_CORE_1_RESET_OFFSET)
+#define SRC_SCR_CORE_2_RESET_OFFSET    15
+#define SRC_SCR_CORE_2_RESET_MASK      (1 << SRC_SCR_CORE_2_RESET_OFFSET)
+#define SRC_SCR_CORE_3_RESET_OFFSET    16
+#define SRC_SCR_CORE_3_RESET_MASK      (1 << SRC_SCR_CORE_3_RESET_OFFSET)
+#define SRC_SCR_CORE_1_ENABLE_OFFSET   22
+#define SRC_SCR_CORE_1_ENABLE_MASK     (1 << SRC_SCR_CORE_1_ENABLE_OFFSET)
+#define SRC_SCR_CORE_2_ENABLE_OFFSET   23
+#define SRC_SCR_CORE_2_ENABLE_MASK     (1 << SRC_SCR_CORE_2_ENABLE_OFFSET)
+#define SRC_SCR_CORE_3_ENABLE_OFFSET   24
+#define SRC_SCR_CORE_3_ENABLE_MASK     (1 << SRC_SCR_CORE_3_ENABLE_OFFSET)
 
 /* WEIM registers */
 struct weim {
@@ -377,17 +377,17 @@ struct src {
        u32     reserved1[2];
        u32     sisr;
        u32     simr;
-       u32     sbmr2;
-       u32     gpr1;
-       u32     gpr2;
-       u32     gpr3;
-       u32     gpr4;
-       u32     gpr5;
-       u32     gpr6;
-       u32     gpr7;
-       u32     gpr8;
-       u32     gpr9;
-       u32     gpr10;
+       u32     sbmr2;
+       u32     gpr1;
+       u32     gpr2;
+       u32     gpr3;
+       u32     gpr4;
+       u32     gpr5;
+       u32     gpr6;
+       u32     gpr7;
+       u32     gpr8;
+       u32     gpr9;
+       u32     gpr10;
 };
 
 /* GPR1 bitfields */
@@ -446,7 +446,7 @@ struct src {
 
 struct iomuxc {
 #ifdef CONFIG_MX6SX
-       u8 reserved[0x4000];
+       u32 reserved[0x1000];
 #endif
        u32 gpr[14];
 };
@@ -587,49 +587,38 @@ struct cspi_regs {
 #endif
 
 struct ocotp_regs {
-       u32     ctrl;
-       u32     ctrl_set;
-       u32     ctrl_clr;
-       u32     ctrl_tog;
-       u32     timing;
-       u32     rsvd0[3];
-       u32     data;
-       u32     rsvd1[3];
-       u32     read_ctrl;
-       u32     rsvd2[3];
-       u32     read_fuse_data;
-       u32     rsvd3[3];
-       u32     sw_sticky;
-       u32     rsvd4[3];
-       u32     scs;
-       u32     scs_set;
-       u32     scs_clr;
-       u32     scs_tog;
-       u32     crc_addr;
-       u32     rsvd5[3];
-       u32     crc_value;
-       u32     rsvd6[3];
-       u32     version;
-       u32     rsvd7[0xdb];
+       mxs_reg_32(ctrl);
+       reg_32(timing);
+       reg_32(data);
+       reg_32(read_ctrl);
+       reg_32(fuse_data);
+       reg_32(sticky);
+       mxs_reg_32(scs);
+       reg_32(crc_addr);
+       reg_32(crc_value);
+       reg_32(version);
+       reg_32(rsvd[0x36]);
 
        struct fuse_bank {
-               u32     fuse_regs[0x20];
+               reg_32(fuse_regs[8]);
        } bank[16];
 };
 
 struct fuse_bank0_regs {
-       u32     lock;
-       u32     rsvd0[3];
-       u32     uid_low;
-       u32     rsvd1[3];
-       u32     uid_high;
-       u32     rsvd2[3];
-       u32     rsvd3[4];
-       u32     rsvd4[4];
-       u32     rsvd5[4];
-       u32     cfg5;
-       u32     rsvd6[3];
-       u32     rsvd7[4];
+       reg_32(misc_conf_lock);
+       union {
+               reg_32(cfg0);
+               reg_32(uid_low);
+       };
+       union {
+               reg_32(cfg1);
+               reg_32(uid_high);
+       };
+       reg_32(cfg2);
+       reg_32(cfg3);
+       reg_32(cfg4);
+       reg_32(cfg5);
+       reg_32(cfg6);
 };
 
 #ifdef CONFIG_MX6SX
@@ -649,18 +638,19 @@ struct fuse_bank4_regs {
 };
 #else
 struct fuse_bank4_regs {
-       u32     sjc_resp_low;
-       u32     rsvd0[3];
-       u32     sjc_resp_high;
-       u32     rsvd1[3];
-       u32     mac_addr_low;
-       u32     rsvd2[3];
-       u32     mac_addr_high;
-       u32     rsvd3[0xb];
-       u32     gp1;
-       u32     rsvd4[3];
-       u32     gp2;
-       u32     rsvd5[3];
+       reg_32(sjc_resp_low);
+       reg_32(sjc_resp_high);
+       reg_32(mac_addr_low);
+       reg_32(mac_addr_high);
+       reg_32(rsvd[2]);
+       reg_32(gp1);
+       reg_32(gp2);
+};
+
+struct fuse_bank5_regs {
+       reg_32(rsvd[5]);
+       reg_32(pad_settings);
+       reg_32(field_return);
 };
 #endif
 
@@ -676,155 +666,55 @@ struct aipstz_regs {
 };
 
 struct anatop_regs {
-       u32     pll_sys;                /* 0x000 */
-       u32     pll_sys_set;            /* 0x004 */
-       u32     pll_sys_clr;            /* 0x008 */
-       u32     pll_sys_tog;            /* 0x00c */
-       u32     usb1_pll_480_ctrl;      /* 0x010 */
-       u32     usb1_pll_480_ctrl_set;  /* 0x014 */
-       u32     usb1_pll_480_ctrl_clr;  /* 0x018 */
-       u32     usb1_pll_480_ctrl_tog;  /* 0x01c */
-       u32     usb2_pll_480_ctrl;      /* 0x020 */
-       u32     usb2_pll_480_ctrl_set;  /* 0x024 */
-       u32     usb2_pll_480_ctrl_clr;  /* 0x028 */
-       u32     usb2_pll_480_ctrl_tog;  /* 0x02c */
-       u32     pll_528;                /* 0x030 */
-       u32     pll_528_set;            /* 0x034 */
-       u32     pll_528_clr;            /* 0x038 */
-       u32     pll_528_tog;            /* 0x03c */
-       u32     pll_528_ss;             /* 0x040 */
-       u32     rsvd0[3];
-       u32     pll_528_num;            /* 0x050 */
-       u32     rsvd1[3];
-       u32     pll_528_denom;          /* 0x060 */
-       u32     rsvd2[3];
-       u32     pll_audio;              /* 0x070 */
-       u32     pll_audio_set;          /* 0x074 */
-       u32     pll_audio_clr;          /* 0x078 */
-       u32     pll_audio_tog;          /* 0x07c */
-       u32     pll_audio_num;          /* 0x080 */
-       u32     rsvd3[3];
-       u32     pll_audio_denom;        /* 0x090 */
-       u32     rsvd4[3];
-       u32     pll_video;              /* 0x0a0 */
-       u32     pll_video_set;          /* 0x0a4 */
-       u32     pll_video_clr;          /* 0x0a8 */
-       u32     pll_video_tog;          /* 0x0ac */
-       u32     pll_video_num;          /* 0x0b0 */
-       u32     rsvd5[3];
-       u32     pll_video_denom;        /* 0x0c0 */
-       u32     rsvd6[3];
-       u32     pll_mlb;                /* 0x0d0 */
-       u32     pll_mlb_set;            /* 0x0d4 */
-       u32     pll_mlb_clr;            /* 0x0d8 */
-       u32     pll_mlb_tog;            /* 0x0dc */
-       u32     pll_enet;               /* 0x0e0 */
-       u32     pll_enet_set;           /* 0x0e4 */
-       u32     pll_enet_clr;           /* 0x0e8 */
-       u32     pll_enet_tog;           /* 0x0ec */
-       u32     pfd_480;                /* 0x0f0 */
-       u32     pfd_480_set;            /* 0x0f4 */
-       u32     pfd_480_clr;            /* 0x0f8 */
-       u32     pfd_480_tog;            /* 0x0fc */
-       u32     pfd_528;                /* 0x100 */
-       u32     pfd_528_set;            /* 0x104 */
-       u32     pfd_528_clr;            /* 0x108 */
-       u32     pfd_528_tog;            /* 0x10c */
-       u32     reg_1p1;                /* 0x110 */
-       u32     reg_1p1_set;            /* 0x114 */
-       u32     reg_1p1_clr;            /* 0x118 */
-       u32     reg_1p1_tog;            /* 0x11c */
-       u32     reg_3p0;                /* 0x120 */
-       u32     reg_3p0_set;            /* 0x124 */
-       u32     reg_3p0_clr;            /* 0x128 */
-       u32     reg_3p0_tog;            /* 0x12c */
-       u32     reg_2p5;                /* 0x130 */
-       u32     reg_2p5_set;            /* 0x134 */
-       u32     reg_2p5_clr;            /* 0x138 */
-       u32     reg_2p5_tog;            /* 0x13c */
-       u32     reg_core;               /* 0x140 */
-       u32     reg_core_set;           /* 0x144 */
-       u32     reg_core_clr;           /* 0x148 */
-       u32     reg_core_tog;           /* 0x14c */
-       u32     ana_misc0;              /* 0x150 */
-       u32     ana_misc0_set;          /* 0x154 */
-       u32     ana_misc0_clr;          /* 0x158 */
-       u32     ana_misc0_tog;          /* 0x15c */
-       u32     ana_misc1;              /* 0x160 */
-       u32     ana_misc1_set;          /* 0x164 */
-       u32     ana_misc1_clr;          /* 0x168 */
-       u32     ana_misc1_tog;          /* 0x16c */
-       u32     ana_misc2;              /* 0x170 */
-       u32     ana_misc2_set;          /* 0x174 */
-       u32     ana_misc2_clr;          /* 0x178 */
-       u32     ana_misc2_tog;          /* 0x17c */
-       u32     tempsense0;             /* 0x180 */
-       u32     tempsense0_set;         /* 0x184 */
-       u32     tempsense0_clr;         /* 0x188 */
-       u32     tempsense0_tog;         /* 0x18c */
-       u32     tempsense1;             /* 0x190 */
-       u32     tempsense1_set;         /* 0x194 */
-       u32     tempsense1_clr;         /* 0x198 */
-       u32     tempsense1_tog;         /* 0x19c */
-       u32     usb1_vbus_detect;       /* 0x1a0 */
-       u32     usb1_vbus_detect_set;   /* 0x1a4 */
-       u32     usb1_vbus_detect_clr;   /* 0x1a8 */
-       u32     usb1_vbus_detect_tog;   /* 0x1ac */
-       u32     usb1_chrg_detect;       /* 0x1b0 */
-       u32     usb1_chrg_detect_set;   /* 0x1b4 */
-       u32     usb1_chrg_detect_clr;   /* 0x1b8 */
-       u32     usb1_chrg_detect_tog;   /* 0x1bc */
-       u32     usb1_vbus_det_stat;     /* 0x1c0 */
-       u32     usb1_vbus_det_stat_set; /* 0x1c4 */
-       u32     usb1_vbus_det_stat_clr; /* 0x1c8 */
-       u32     usb1_vbus_det_stat_tog; /* 0x1cc */
-       u32     usb1_chrg_det_stat;     /* 0x1d0 */
-       u32     usb1_chrg_det_stat_set; /* 0x1d4 */
-       u32     usb1_chrg_det_stat_clr; /* 0x1d8 */
-       u32     usb1_chrg_det_stat_tog; /* 0x1dc */
-       u32     usb1_loopback;          /* 0x1e0 */
-       u32     usb1_loopback_set;      /* 0x1e4 */
-       u32     usb1_loopback_clr;      /* 0x1e8 */
-       u32     usb1_loopback_tog;      /* 0x1ec */
-       u32     usb1_misc;              /* 0x1f0 */
-       u32     usb1_misc_set;          /* 0x1f4 */
-       u32     usb1_misc_clr;          /* 0x1f8 */
-       u32     usb1_misc_tog;          /* 0x1fc */
-       u32     usb2_vbus_detect;       /* 0x200 */
-       u32     usb2_vbus_detect_set;   /* 0x204 */
-       u32     usb2_vbus_detect_clr;   /* 0x208 */
-       u32     usb2_vbus_detect_tog;   /* 0x20c */
-       u32     usb2_chrg_detect;       /* 0x210 */
-       u32     usb2_chrg_detect_set;   /* 0x214 */
-       u32     usb2_chrg_detect_clr;   /* 0x218 */
-       u32     usb2_chrg_detect_tog;   /* 0x21c */
-       u32     usb2_vbus_det_stat;     /* 0x220 */
-       u32     usb2_vbus_det_stat_set; /* 0x224 */
-       u32     usb2_vbus_det_stat_clr; /* 0x228 */
-       u32     usb2_vbus_det_stat_tog; /* 0x22c */
-       u32     usb2_chrg_det_stat;     /* 0x230 */
-       u32     usb2_chrg_det_stat_set; /* 0x234 */
-       u32     usb2_chrg_det_stat_clr; /* 0x238 */
-       u32     usb2_chrg_det_stat_tog; /* 0x23c */
-       u32     usb2_loopback;          /* 0x240 */
-       u32     usb2_loopback_set;      /* 0x244 */
-       u32     usb2_loopback_clr;      /* 0x248 */
-       u32     usb2_loopback_tog;      /* 0x24c */
-       u32     usb2_misc;              /* 0x250 */
-       u32     usb2_misc_set;          /* 0x254 */
-       u32     usb2_misc_clr;          /* 0x258 */
-       u32     usb2_misc_tog;          /* 0x25c */
-       u32     digprog;                /* 0x260 */
-       u32     reserved1[7];
-       u32     digprog_sololite;       /* 0x280 */
+       mxs_reg_32(pll_arm);            /* 0x000 */
+       mxs_reg_32(usb1_pll_480_ctrl);  /* 0x010 */
+       mxs_reg_32(usb2_pll_480_ctrl);  /* 0x020 */
+       mxs_reg_32(pll_528);            /* 0x030 */
+       reg_32(pll_528_ss);             /* 0x040 */
+       reg_32(pll_528_num);            /* 0x050 */
+       reg_32(pll_528_denom);          /* 0x060 */
+       mxs_reg_32(pll_audio);          /* 0x070 */
+       reg_32(pll_audio_num);          /* 0x080 */
+       reg_32(pll_audio_denom);        /* 0x090 */
+       mxs_reg_32(pll_video);          /* 0x0a0 */
+       reg_32(pll_video_num);          /* 0x0b0 */
+       reg_32(pll_video_denom);        /* 0x0c0 */
+       mxs_reg_32(pll_mlb);            /* 0x0d0 */
+       mxs_reg_32(pll_enet);           /* 0x0e0 */
+       mxs_reg_32(pfd_480);            /* 0x0f0 */
+       mxs_reg_32(pfd_528);            /* 0x100 */
+       mxs_reg_32(reg_1p1);            /* 0x110 */
+       mxs_reg_32(reg_3p0);            /* 0x120 */
+       mxs_reg_32(reg_2p5);            /* 0x130 */
+       mxs_reg_32(reg_core);           /* 0x140 */
+       mxs_reg_32(ana_misc0);          /* 0x150 */
+       mxs_reg_32(ana_misc1);          /* 0x160 */
+       mxs_reg_32(ana_misc2);          /* 0x170 */
+       mxs_reg_32(tempsense0);         /* 0x180 */
+       mxs_reg_32(tempsense1);         /* 0x190 */
+       mxs_reg_32(usb1_vbus_detect);   /* 0x1a0 */
+       mxs_reg_32(usb1_chrg_detect);   /* 0x1b0 */
+       mxs_reg_32(usb1_vbus_det_stat); /* 0x1c0 */
+       mxs_reg_32(usb1_chrg_det_stat); /* 0x1d0 */
+       mxs_reg_32(usb1_loopback);      /* 0x1e0 */
+       mxs_reg_32(usb1_misc);          /* 0x1f0 */
+       mxs_reg_32(usb2_vbus_detect);   /* 0x200 */
+       mxs_reg_32(usb2_chrg_detect);   /* 0x210 */
+       mxs_reg_32(usb2_vbus_det_stat); /* 0x220 */
+       mxs_reg_32(usb2_chrg_det_stat); /* 0x230 */
+       mxs_reg_32(usb2_loopback);      /* 0x240 */
+       mxs_reg_32(usb2_misc);          /* 0x250 */
+       reg_32(digprog);                /* 0x260 */
+       reg_32(rsrvd);                  /* 0x270 */
+       reg_32(digprog_sololite);       /* 0x280 */
 };
 
-#define ANATOP_PFD_FRAC_SHIFT(n)       ((n)*8)
-#define ANATOP_PFD_FRAC_MASK(n)        (0x3f<<ANATOP_PFD_FRAC_SHIFT(n))
-#define ANATOP_PFD_STABLE_SHIFT(n)     (6+((n)*8))
-#define ANATOP_PFD_STABLE_MASK(n)      (1<<ANATOP_PFD_STABLE_SHIFT(n))
-#define ANATOP_PFD_CLKGATE_SHIFT(n)    (7+((n)*8))
-#define ANATOP_PFD_CLKGATE_MASK(n)     (1<<ANATOP_PFD_CLKGATE_SHIFT(n))
+#define ANATOP_PFD_FRAC_SHIFT(n)       ((n) * 8)
+#define ANATOP_PFD_FRAC_MASK(n)                (0x3f << ANATOP_PFD_FRAC_SHIFT(n))
+#define ANATOP_PFD_STABLE_SHIFT(n)     (6 + ((n) * 8))
+#define ANATOP_PFD_STABLE_MASK(n)      (1 << ANATOP_PFD_STABLE_SHIFT(n))
+#define ANATOP_PFD_CLKGATE_SHIFT(n)    (7 + ((n) * 8))
+#define ANATOP_PFD_CLKGATE_MASK(n)     (1 << ANATOP_PFD_CLKGATE_SHIFT(n))
 
 struct wdog_regs {
        u16     wcr;    /* Control */
@@ -834,7 +724,7 @@ struct wdog_regs {
        u16     wmcr;   /* Miscellaneous Control */
 };
 
-#define PWMCR_PRESCALER(x)     (((x - 1) & 0xFFF) << 4)
+#define PWMCR_PRESCALER(x)     ((((x) - 1) & 0xFFF) << 4)
 #define PWMCR_DOZEEN           (1 << 24)
 #define PWMCR_WAITEN           (1 << 23)
 #define PWMCR_DBGEN            (1 << 22)
diff --git a/arch/arm/include/asm/arch-mx6/regs-ocotp.h b/arch/arm/include/asm/arch-mx6/regs-ocotp.h
new file mode 100644 (file)
index 0000000..2b21bb3
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Freescale i.MX6 OCOTP Register Definitions
+ *
+ * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ * based on:
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * Based on code from LTIB:
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#ifndef __MX6_REGS_OCOTP_H__
+#define __MX6_REGS_OCOTP_H__
+
+#ifndef        __ASSEMBLY__
+#define mx6_ocotp_reg_32(r)    mxs_reg_32(hw_ocotp_##r)
+#define ocotp_reg_32(r)                reg_32(hw_ocotp_##r)
+
+struct mx6_ocotp_regs {
+       mx6_ocotp_reg_32(ctrl);                 /* 0x000 */
+       ocotp_reg_32(timing);                   /* 0x010 */
+       ocotp_reg_32(data);                     /* 0x020 */
+       ocotp_reg_32(read_ctrl);                /* 0x030 */
+       ocotp_reg_32(read_fuse_data);           /* 0x040 */
+       ocotp_reg_32(sw_sticky);                /* 0x050 */
+       mx6_ocotp_reg_32(scs);                  /* 0x060 */
+       reg_32(rsrvd1);                         /* 0x070 */
+       reg_32(rsrvd2);                         /* 0x080 */
+       ocotp_reg_32(version);                  /* 0x090 */
+
+       reg_32(rsrvd3[54]);                     /* 0x0a0 - 0x3ff */
+
+       /* bank 0 */
+       ocotp_reg_32(lock);                     /* 0x400 */
+       ocotp_reg_32(cfg0);                     /* 0x410 */
+       ocotp_reg_32(cfg1);                     /* 0x420 */
+       ocotp_reg_32(cfg2);                     /* 0x430 */
+       ocotp_reg_32(cfg3);                     /* 0x440 */
+       ocotp_reg_32(cfg4);                     /* 0x450 */
+       ocotp_reg_32(cfg5);                     /* 0x460 */
+       ocotp_reg_32(cfg6);                     /* 0x470 */
+
+       /* bank 1 */
+       ocotp_reg_32(mem0);                     /* 0x480 */
+       ocotp_reg_32(mem1);                     /* 0x490 */
+       ocotp_reg_32(mem2);                     /* 0x4a0 */
+       ocotp_reg_32(mem3);                     /* 0x4b0 */
+       ocotp_reg_32(mem4);                     /* 0x4c0 */
+       ocotp_reg_32(ana0);                     /* 0x4d0 */
+       ocotp_reg_32(ana1);                     /* 0x4e0 */
+       ocotp_reg_32(ana2);                     /* 0x4f0 */
+
+       /* bank 2 */
+       reg_32(rsrvd4[8]);                      /* 0x500 - 0x57f */
+
+       /* bank 3 */
+       ocotp_reg_32(srk0);                     /* 0x580 */
+       ocotp_reg_32(srk1);                     /* 0x590 */
+       ocotp_reg_32(srk2);                     /* 0x5a0 */
+       ocotp_reg_32(srk3);                     /* 0x5b0 */
+       ocotp_reg_32(srk4);                     /* 0x5c0 */
+       ocotp_reg_32(srk5);                     /* 0x5d0 */
+       ocotp_reg_32(srk6);                     /* 0x5e0 */
+       ocotp_reg_32(srk7);                     /* 0x5f0 */
+
+       /* bank 4 */
+       ocotp_reg_32(hsjc_resp0);               /* 0x600 */
+       ocotp_reg_32(hsjc_resp1);               /* 0x610 */
+       ocotp_reg_32(mac0);                     /* 0x620 */
+       ocotp_reg_32(mac1);                     /* 0x630 */
+       reg_32(rsrvd5[2]);                      /* 0x640 - 0x65f */
+       ocotp_reg_32(gp1);                      /* 0x660 */
+       ocotp_reg_32(gp2);                      /* 0x670 */
+
+       /* bank 5 */
+       reg_32(rsrvd6[5]);                      /* 0x680 - 0x6cf */
+       ocotp_reg_32(misc_conf);                /* 0x6d0 */
+       ocotp_reg_32(field_return);             /* 0x6e0 */
+       ocotp_reg_32(srk_revoke);               /* 0x6f0 */
+};
+
+#endif
+
+#define OCOTP_CTRL_BUSY                                (1 << 8)
+#define OCOTP_CTRL_ERROR                       (1 << 9)
+#define OCOTP_CTRL_RELOAD_SHADOWS              (1 << 10)
+
+#define OCOTP_RD_CTRL_READ_FUSE                        (1 << 0)
+
+#define        OCOTP_VERSION_MAJOR_MASK                (0xff << 24)
+#define        OCOTP_VERSION_MAJOR_OFFSET              24
+#define        OCOTP_VERSION_MINOR_MASK                (0xff << 16)
+#define        OCOTP_VERSION_MINOR_OFFSET              16
+#define        OCOTP_VERSION_STEP_MASK                 0xffff
+#define        OCOTP_VERSION_STEP_OFFSET               0
+
+#endif /* __MX6_REGS_OCOTP_H__ */
index 28ba84415f05b667d24dd329f1a1953189e67a53..8e92e8567fe5fe22e9a3465ade77ca7375cf353b 100644 (file)
@@ -28,6 +28,11 @@ const char *get_imx_type(u32 imxtype);
 unsigned imx_ddr_size(void);
 void set_chipselect_size(int const);
 
+
+struct mxs_register_32;
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+
 /*
  * Initializes on-chip ethernet controllers.
  * to override, implement board_eth_init()
@@ -44,4 +49,7 @@ int mxs_wait_mask_set(struct mxs_register_32 *reg,
 int mxs_wait_mask_clr(struct mxs_register_32 *reg,
                       uint32_t mask,
                       unsigned int timeout);
+
+int read_cpu_temperature(void);
+int check_cpu_temperature(int boot);
 #endif
index fc9d75b50940504c874f914cb3d8731e23ce67a7..d3bc95b8240ac270c8fa5920dde868bdffbacf83 100644 (file)
@@ -25,6 +25,7 @@ enum mxc_clock {
        MXC_SSP2_CLK,
        MXC_SSP3_CLK,
 #endif
+       MXC_XBUS_CLK,
 };
 
 enum mxs_ioclock {
index 1490ffd520e52a9e023929fbd90f82ba60a8d36f..10dbf4e5fa49d43c70d70960c89f5269990b8ac0 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_clkctrl_regs {
-       mxs_reg_32(hw_clkctrl_pll0ctrl0)        /* 0x00 */
-       uint32_t        hw_clkctrl_pll0ctrl1;   /* 0x10 */
-       uint32_t        reserved_pll0ctrl1[3];  /* 0x14-0x1c */
-       mxs_reg_32(hw_clkctrl_pll1ctrl0)        /* 0x20 */
-       uint32_t        hw_clkctrl_pll1ctrl1;   /* 0x30 */
-       uint32_t        reserved_pll1ctrl1[3];  /* 0x34-0x3c */
-       mxs_reg_32(hw_clkctrl_pll2ctrl0)        /* 0x40 */
-       mxs_reg_32(hw_clkctrl_cpu)              /* 0x50 */
-       mxs_reg_32(hw_clkctrl_hbus)             /* 0x60 */
-       mxs_reg_32(hw_clkctrl_xbus)             /* 0x70 */
-       mxs_reg_32(hw_clkctrl_xtal)             /* 0x80 */
-       mxs_reg_32(hw_clkctrl_ssp0)             /* 0x90 */
-       mxs_reg_32(hw_clkctrl_ssp1)             /* 0xa0 */
-       mxs_reg_32(hw_clkctrl_ssp2)             /* 0xb0 */
-       mxs_reg_32(hw_clkctrl_ssp3)             /* 0xc0 */
-       mxs_reg_32(hw_clkctrl_gpmi)             /* 0xd0 */
-       mxs_reg_32(hw_clkctrl_spdif)            /* 0xe0 */
-       mxs_reg_32(hw_clkctrl_emi)              /* 0xf0 */
-       mxs_reg_32(hw_clkctrl_saif0)            /* 0x100 */
-       mxs_reg_32(hw_clkctrl_saif1)            /* 0x110 */
-       mxs_reg_32(hw_clkctrl_lcdif)            /* 0x120 */
-       mxs_reg_32(hw_clkctrl_etm)              /* 0x130 */
-       mxs_reg_32(hw_clkctrl_enet)             /* 0x140 */
-       mxs_reg_32(hw_clkctrl_hsadc)            /* 0x150 */
-       mxs_reg_32(hw_clkctrl_flexcan)          /* 0x160 */
+       mxs_reg_32(hw_clkctrl_pll0ctrl0);       /* 0x00 */
+       reg_32(hw_clkctrl_pll0ctrl1);           /* 0x10 */
+       mxs_reg_32(hw_clkctrl_pll1ctrl0);       /* 0x20 */
+       reg_32(hw_clkctrl_pll1ctrl1);           /* 0x30 */
+       mxs_reg_32(hw_clkctrl_pll2ctrl0);       /* 0x40 */
+       mxs_reg_32(hw_clkctrl_cpu);             /* 0x50 */
+       mxs_reg_32(hw_clkctrl_hbus);            /* 0x60 */
+       reg_32(hw_clkctrl_xbus);                /* 0x70 */
+       mxs_reg_32(hw_clkctrl_xtal);            /* 0x80 */
+       reg_32(hw_clkctrl_ssp0);                /* 0x90 */
+       reg_32(hw_clkctrl_ssp1);                /* 0xa0 */
+       reg_32(hw_clkctrl_ssp2);                /* 0xb0 */
+       reg_32(hw_clkctrl_ssp3);                /* 0xc0 */
+       reg_32(hw_clkctrl_gpmi);                /* 0xd0 */
+       reg_32(hw_clkctrl_spdif);               /* 0xe0 */
+       reg_32(hw_clkctrl_emi);                 /* 0xf0 */
+       reg_32(hw_clkctrl_saif0);               /* 0x100 */
+       reg_32(hw_clkctrl_saif1);               /* 0x110 */
+       reg_32(hw_clkctrl_lcdif);               /* 0x120 */
+       reg_32(hw_clkctrl_etm);                 /* 0x130 */
+       reg_32(hw_clkctrl_enet);                /* 0x140 */
+       reg_32(hw_clkctrl_hsadc);               /* 0x150 */
+       reg_32(hw_clkctrl_flexcan);             /* 0x160 */
 
-       uint32_t        reserved[16];
+       reg_32(reserved[4]);                    /* 0x170-0x1a0 */
 
-       mxs_reg_8(hw_clkctrl_frac0)             /* 0x1b0 */
-       mxs_reg_8(hw_clkctrl_frac1)             /* 0x1c0 */
-       mxs_reg_32(hw_clkctrl_clkseq)           /* 0x1d0 */
-       mxs_reg_32(hw_clkctrl_reset)            /* 0x1e0 */
-       mxs_reg_32(hw_clkctrl_status)           /* 0x1f0 */
-       mxs_reg_32(hw_clkctrl_version)          /* 0x200 */
+       mxs_reg_8(hw_clkctrl_frac0);            /* 0x1b0 */
+       mxs_reg_8(hw_clkctrl_frac1);            /* 0x1c0 */
+       mxs_reg_32(hw_clkctrl_clkseq);          /* 0x1d0 */
+       reg_32(hw_clkctrl_reset);               /* 0x1e0 */
+       reg_32(hw_clkctrl_status);              /* 0x1f0 */
+       reg_32(hw_clkctrl_version);             /* 0x200 */
 };
 #endif
 
index 860be9e28f4561fab2dfba7be5e5dc328bd3ea80..a09a9976b0d6ab2c2045bba7484f3adc8c9bdb59 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_digctl_regs {
-       mxs_reg_32(hw_digctl_ctrl)                              /* 0x000 */
-       mxs_reg_32(hw_digctl_status)                            /* 0x010 */
-       mxs_reg_32(hw_digctl_hclkcount)                 /* 0x020 */
-       mxs_reg_32(hw_digctl_ramctrl)                           /* 0x030 */
-       mxs_reg_32(hw_digctl_emi_status)                        /* 0x040 */
-       mxs_reg_32(hw_digctl_read_margin)                       /* 0x050 */
+       mxs_reg_32(hw_digctl_ctrl);                             /* 0x000 */
+       mxs_reg_32(hw_digctl_status);                           /* 0x010 */
+       mxs_reg_32(hw_digctl_hclkcount);                        /* 0x020 */
+       mxs_reg_32(hw_digctl_ramctrl);                          /* 0x030 */
+       mxs_reg_32(hw_digctl_emi_status);                       /* 0x040 */
+       mxs_reg_32(hw_digctl_read_margin);                      /* 0x050 */
        uint32_t        hw_digctl_writeonce;                    /* 0x060 */
        uint32_t        reserved_writeonce[3];
-       mxs_reg_32(hw_digctl_bist_ctl)                          /* 0x070 */
-       mxs_reg_32(hw_digctl_bist_status)                       /* 0x080 */
+       mxs_reg_32(hw_digctl_bist_ctl);                         /* 0x070 */
+       mxs_reg_32(hw_digctl_bist_status);                      /* 0x080 */
        uint32_t        hw_digctl_entropy;                      /* 0x090 */
        uint32_t        reserved_entropy[3];
        uint32_t        hw_digctl_entropy_latched;              /* 0x0a0 */
@@ -30,7 +30,7 @@ struct mxs_digctl_regs {
 
        uint32_t        reserved1[4];
 
-       mxs_reg_32(hw_digctl_microseconds)                      /* 0x0c0 */
+       mxs_reg_32(hw_digctl_microseconds);                     /* 0x0c0 */
        uint32_t        hw_digctl_dbgrd;                        /* 0x0d0 */
        uint32_t        reserved_hw_digctl_dbgrd[3];
        uint32_t        hw_digctl_dbg;                          /* 0x0e0 */
@@ -38,21 +38,21 @@ struct mxs_digctl_regs {
 
        uint32_t        reserved2[4];
 
-       mxs_reg_32(hw_digctl_usb_loopback)                      /* 0x100 */
-       mxs_reg_32(hw_digctl_ocram_status0)                     /* 0x110 */
-       mxs_reg_32(hw_digctl_ocram_status1)                     /* 0x120 */
-       mxs_reg_32(hw_digctl_ocram_status2)                     /* 0x130 */
-       mxs_reg_32(hw_digctl_ocram_status3)                     /* 0x140 */
-       mxs_reg_32(hw_digctl_ocram_status4)                     /* 0x150 */
-       mxs_reg_32(hw_digctl_ocram_status5)                     /* 0x160 */
-       mxs_reg_32(hw_digctl_ocram_status6)                     /* 0x170 */
-       mxs_reg_32(hw_digctl_ocram_status7)                     /* 0x180 */
-       mxs_reg_32(hw_digctl_ocram_status8)                     /* 0x190 */
-       mxs_reg_32(hw_digctl_ocram_status9)                     /* 0x1a0 */
-       mxs_reg_32(hw_digctl_ocram_status10)                    /* 0x1b0 */
-       mxs_reg_32(hw_digctl_ocram_status11)                    /* 0x1c0 */
-       mxs_reg_32(hw_digctl_ocram_status12)                    /* 0x1d0 */
-       mxs_reg_32(hw_digctl_ocram_status13)                    /* 0x1e0 */
+       mxs_reg_32(hw_digctl_usb_loopback);                     /* 0x100 */
+       mxs_reg_32(hw_digctl_ocram_status0);                    /* 0x110 */
+       mxs_reg_32(hw_digctl_ocram_status1);                    /* 0x120 */
+       mxs_reg_32(hw_digctl_ocram_status2);                    /* 0x130 */
+       mxs_reg_32(hw_digctl_ocram_status3);                    /* 0x140 */
+       mxs_reg_32(hw_digctl_ocram_status4);                    /* 0x150 */
+       mxs_reg_32(hw_digctl_ocram_status5);                    /* 0x160 */
+       mxs_reg_32(hw_digctl_ocram_status6);                    /* 0x170 */
+       mxs_reg_32(hw_digctl_ocram_status7);                    /* 0x180 */
+       mxs_reg_32(hw_digctl_ocram_status8);                    /* 0x190 */
+       mxs_reg_32(hw_digctl_ocram_status9);                    /* 0x1a0 */
+       mxs_reg_32(hw_digctl_ocram_status10);                   /* 0x1b0 */
+       mxs_reg_32(hw_digctl_ocram_status11);                   /* 0x1c0 */
+       mxs_reg_32(hw_digctl_ocram_status12);                   /* 0x1d0 */
+       mxs_reg_32(hw_digctl_ocram_status13);                   /* 0x1e0 */
 
        uint32_t        reserved3[36];
 
@@ -62,7 +62,7 @@ struct mxs_digctl_regs {
        uint32_t        reserved_hw_digctl_scratch1[3];
        uint32_t        hw_digctl_armcache;                     /* 0x2a0 */
        uint32_t        reserved_hw_digctl_armcache[3];
-       mxs_reg_32(hw_digctl_debug_trap)                        /* 0x2b0 */
+       mxs_reg_32(hw_digctl_debug_trap);                       /* 0x2b0 */
        uint32_t        hw_digctl_debug_trap_l0_addr_low;       /* 0x2c0 */
        uint32_t        reserved_hw_digctl_debug_trap_l0_addr_low[3];
        uint32_t        hw_digctl_debug_trap_l0_addr_high;      /* 0x2d0 */
index a58303efb8d9578cbac308feea0c2dc8561946df..77ddd0bc49d26d9c1efe37199e6d29e45ea36c68 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_i2c_regs {
-       mxs_reg_32(hw_i2c_ctrl0)
-       mxs_reg_32(hw_i2c_timing0)
-       mxs_reg_32(hw_i2c_timing1)
-       mxs_reg_32(hw_i2c_timing2)
-       mxs_reg_32(hw_i2c_ctrl1)
-       mxs_reg_32(hw_i2c_stat)
-       mxs_reg_32(hw_i2c_queuectrl)
-       mxs_reg_32(hw_i2c_queuestat)
-       mxs_reg_32(hw_i2c_queuecmd)
-       mxs_reg_32(hw_i2c_queuedata)
-       mxs_reg_32(hw_i2c_data)
-       mxs_reg_32(hw_i2c_debug0)
-       mxs_reg_32(hw_i2c_debug1)
-       mxs_reg_32(hw_i2c_version)
+       mxs_reg_32(hw_i2c_ctrl0);
+       mxs_reg_32(hw_i2c_timing0);
+       mxs_reg_32(hw_i2c_timing1);
+       mxs_reg_32(hw_i2c_timing2);
+       mxs_reg_32(hw_i2c_ctrl1);
+       mxs_reg_32(hw_i2c_stat);
+       mxs_reg_32(hw_i2c_queuectrl);
+       mxs_reg_32(hw_i2c_queuestat);
+       mxs_reg_32(hw_i2c_queuecmd);
+       mxs_reg_32(hw_i2c_queuedata);
+       mxs_reg_32(hw_i2c_data);
+       mxs_reg_32(hw_i2c_debug0);
+       mxs_reg_32(hw_i2c_debug1);
+       mxs_reg_32(hw_i2c_version);
 };
 #endif
 
index 8915d84d0d735b0bc99a042d402421275d1282ce..a845883911b02204ad7d5f16613d0e1a296ad4d8 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_lcdif_regs {
-       mxs_reg_32(hw_lcdif_ctrl)               /* 0x00 */
-       mxs_reg_32(hw_lcdif_ctrl1)              /* 0x10 */
+       mxs_reg_32(hw_lcdif_ctrl);              /* 0x00 */
+       mxs_reg_32(hw_lcdif_ctrl1);             /* 0x10 */
 #if defined(CONFIG_MX28)
        mxs_reg_32(hw_lcdif_ctrl2)              /* 0x20 */
-#endif
-       mxs_reg_32(hw_lcdif_transfer_count)     /* 0x20/0x30 */
-       mxs_reg_32(hw_lcdif_cur_buf)            /* 0x30/0x40 */
-       mxs_reg_32(hw_lcdif_next_buf)           /* 0x40/0x50 */
+#endif                                         /* MX23/MX28 */
+       mxs_reg_32(hw_lcdif_transfer_count);    /* 0x20/0x30 */
+       mxs_reg_32(hw_lcdif_cur_buf);           /* 0x30/0x40 */
+       mxs_reg_32(hw_lcdif_next_buf);          /* 0x40/0x50 */
 
 #if defined(CONFIG_MX23)
-       uint32_t        reserved1[4];
+       reg_32(reserved1);                      /* 0x50 */
 #endif
 
-       mxs_reg_32(hw_lcdif_timing)             /* 0x60 */
-       mxs_reg_32(hw_lcdif_vdctrl0)            /* 0x70 */
-       mxs_reg_32(hw_lcdif_vdctrl1)            /* 0x80 */
-       mxs_reg_32(hw_lcdif_vdctrl2)            /* 0x90 */
-       mxs_reg_32(hw_lcdif_vdctrl3)            /* 0xa0 */
-       mxs_reg_32(hw_lcdif_vdctrl4)            /* 0xb0 */
-       mxs_reg_32(hw_lcdif_dvictrl0)           /* 0xc0 */
-       mxs_reg_32(hw_lcdif_dvictrl1)           /* 0xd0 */
-       mxs_reg_32(hw_lcdif_dvictrl2)           /* 0xe0 */
-       mxs_reg_32(hw_lcdif_dvictrl3)           /* 0xf0 */
-       mxs_reg_32(hw_lcdif_dvictrl4)           /* 0x100 */
-       mxs_reg_32(hw_lcdif_csc_coeffctrl0)     /* 0x110 */
-       mxs_reg_32(hw_lcdif_csc_coeffctrl1)     /* 0x120 */
-       mxs_reg_32(hw_lcdif_csc_coeffctrl2)     /* 0x130 */
-       mxs_reg_32(hw_lcdif_csc_coeffctrl3)     /* 0x140 */
-       mxs_reg_32(hw_lcdif_csc_coeffctrl4)     /* 0x150 */
-       mxs_reg_32(hw_lcdif_csc_offset) /* 0x160 */
-       mxs_reg_32(hw_lcdif_csc_limit)          /* 0x170 */
+       mxs_reg_32(hw_lcdif_timing);            /* 0x60 */
+       mxs_reg_32(hw_lcdif_vdctrl0);           /* 0x70 */
+       mxs_reg_32(hw_lcdif_vdctrl1);           /* 0x80 */
+       mxs_reg_32(hw_lcdif_vdctrl2);           /* 0x90 */
+       mxs_reg_32(hw_lcdif_vdctrl3);           /* 0xa0 */
+       mxs_reg_32(hw_lcdif_vdctrl4);           /* 0xb0 */
+       mxs_reg_32(hw_lcdif_dvictrl0);          /* 0xc0 */
+       mxs_reg_32(hw_lcdif_dvictrl1);          /* 0xd0 */
+       mxs_reg_32(hw_lcdif_dvictrl2);          /* 0xe0 */
+       mxs_reg_32(hw_lcdif_dvictrl3);          /* 0xf0 */
+       mxs_reg_32(hw_lcdif_dvictrl4);          /* 0x100 */
+       mxs_reg_32(hw_lcdif_csc_coeffctrl0);    /* 0x110 */
+       mxs_reg_32(hw_lcdif_csc_coeffctrl1);    /* 0x120 */
+       mxs_reg_32(hw_lcdif_csc_coeffctrl2);    /* 0x130 */
+       mxs_reg_32(hw_lcdif_csc_coeffctrl3);    /* 0x140 */
+       mxs_reg_32(hw_lcdif_csc_coeffctrl4);    /* 0x150 */
+       mxs_reg_32(hw_lcdif_csc_offset);        /* 0x160 */
+       mxs_reg_32(hw_lcdif_csc_limit);         /* 0x170 */
 
 #if defined(CONFIG_MX23)
-       uint32_t        reserved2[12];
-#endif
+       reg_32(reserved2[3]);                   /* 0x180-0x1a0 */
+#endif                                         /*  MX23/MX28 */
        mxs_reg_32(hw_lcdif_data)               /* 0x1b0/0x180 */
        mxs_reg_32(hw_lcdif_bm_error_stat)      /* 0x1c0/0x190 */
 #if defined(CONFIG_MX28)
-       mxs_reg_32(hw_lcdif_crc_stat)           /* 0x1a0 */
+       mxs_reg_32(hw_lcdif_crc_stat)           /*       0x1a0 */
 #endif
-       mxs_reg_32(hw_lcdif_lcdif_stat)         /* 0x1d0/0x1b0 */
-       mxs_reg_32(hw_lcdif_version)            /* 0x1e0/0x1c0 */
-       mxs_reg_32(hw_lcdif_debug0)             /* 0x1f0/0x1d0 */
-       mxs_reg_32(hw_lcdif_debug1)             /* 0x200/0x1e0 */
-       mxs_reg_32(hw_lcdif_debug2)             /* 0x1f0 */
+       mxs_reg_32(hw_lcdif_lcdif_stat);        /* 0x1d0/0x1b0 */
+       mxs_reg_32(hw_lcdif_version);           /* 0x1e0/0x1c0 */
+       mxs_reg_32(hw_lcdif_debug0);            /* 0x1f0/0x1d0 */
+       mxs_reg_32(hw_lcdif_debug1);            /* 0x200/0x1e0 */
+       mxs_reg_32(hw_lcdif_debug2);            /*       0x1f0 */
 };
 #endif
 
@@ -111,6 +111,8 @@ struct mxs_lcdif_regs {
 #define        LCDIF_CTRL1_IRQ_ON_ALTERNATE_FIELDS                     (1 << 20)
 #define        LCDIF_CTRL1_BYTE_PACKING_FORMAT_MASK                    (0xf << 16)
 #define        LCDIF_CTRL1_BYTE_PACKING_FORMAT_OFFSET                  16
+#define        LCDIF_CTRL1_BYTE_PACKING_FORMAT(n)                      (((n) << LCDIF_CTRL1_BYTE_PACKING_FORMAT_OFFSET) & \
+                                               LCDIF_CTRL1_BYTE_PACKING_FORMAT_MASK)
 #define        LCDIF_CTRL1_OVERFLOW_IRQ_EN                             (1 << 15)
 #define        LCDIF_CTRL1_UNDERFLOW_IRQ_EN                            (1 << 14)
 #define        LCDIF_CTRL1_CUR_FRAME_DONE_IRQ_EN                       (1 << 13)
@@ -157,8 +159,12 @@ struct mxs_lcdif_regs {
 
 #define        LCDIF_TRANSFER_COUNT_V_COUNT_MASK                       (0xffff << 16)
 #define        LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET                     16
+#define        LCDIF_TRANSFER_COUNT_V_COUNT(n)                         (((n) << LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET) & \
+                                               LCDIF_TRANSFER_COUNT_V_COUNT_MASK)
 #define        LCDIF_TRANSFER_COUNT_H_COUNT_MASK                       (0xffff << 0)
 #define        LCDIF_TRANSFER_COUNT_H_COUNT_OFFSET                     0
+#define        LCDIF_TRANSFER_COUNT_H_COUNT(n)                         (((n) << LCDIF_TRANSFER_COUNT_H_COUNT_OFFSET) & \
+                                               LCDIF_TRANSFER_COUNT_H_COUNT_MASK)
 
 #define        LCDIF_CUR_BUF_ADDR_MASK                                 0xffffffff
 #define        LCDIF_CUR_BUF_ADDR_OFFSET                               0
@@ -187,9 +193,13 @@ struct mxs_lcdif_regs {
 #define        LCDIF_VDCTRL0_HALF_LINE_MODE                            (1 << 18)
 #define        LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_MASK                    0x3ffff
 #define        LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_OFFSET                  0
+#define        LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH(n)                      (((n) << LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_OFFSET) & \
+                                               LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_MASK)
 
 #define        LCDIF_VDCTRL1_VSYNC_PERIOD_MASK                         0xffffffff
 #define        LCDIF_VDCTRL1_VSYNC_PERIOD_OFFSET                       0
+#define        LCDIF_VDCTRL1_VSYNC_PERIOD(n)                           (((n) << LCDIF_VDCTRL1_VSYNC_PERIOD_OFFSET) & \
+                                               LCDIF_VDCTRL1_VSYNC_PERIOD_MASK)
 
 #if defined(CONFIG_MX23)
 #define        LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_MASK                    (0xff << 24)
@@ -198,20 +208,32 @@ struct mxs_lcdif_regs {
 #define        LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_MASK                    (0x3fff << 18)
 #define        LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_OFFSET                  18
 #endif
+#define        LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH(n)                      (((n) << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_OFFSET) & \
+                                               LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_MASK)
 #define        LCDIF_VDCTRL2_HSYNC_PERIOD_MASK                         0x3ffff
 #define        LCDIF_VDCTRL2_HSYNC_PERIOD_OFFSET                       0
+#define        LCDIF_VDCTRL2_HSYNC_PERIOD(n)                           (((n) << LCDIF_VDCTRL2_HSYNC_PERIOD_OFFSET) & \
+                                               LCDIF_VDCTRL2_HSYNC_PERIOD_MASK)
 
 #define        LCDIF_VDCTRL3_MUX_SYNC_SIGNALS                          (1 << 29)
 #define        LCDIF_VDCTRL3_VSYNC_ONLY                                (1 << 28)
 #define        LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_MASK                  (0xfff << 16)
 #define        LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_OFFSET                16
+#define        LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT(n)                    (((n) << LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_OFFSET) & \
+                                               LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_MASK)
 #define        LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_MASK                    (0xffff << 0)
 #define        LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_OFFSET                  0
+#define        LCDIF_VDCTRL3_VERTICAL_WAIT_CNT(n)                      (((n) << LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_OFFSET) & \
+                                               LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_MASK)
 
 #define        LCDIF_VDCTRL4_DOTCLK_DLY_SEL_MASK                       (0x7 << 29)
 #define        LCDIF_VDCTRL4_DOTCLK_DLY_SEL_OFFSET                     29
+#define        LCDIF_VDCTRL4_DOTCLK_DLY_SEL(n)                         (((n) << LCDIF_VDCTRL4_DOTCLK_DLY_SEL_OFFSET) & \
+                                               LCDIF_VDCTRL4_DOTCLK_DLY_SEL_MASK)
 #define        LCDIF_VDCTRL4_SYNC_SIGNALS_ON                           (1 << 18)
 #define        LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_MASK              0x3ffff
 #define        LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_OFFSET            0
+#define        LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT(n)                (((n) << LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_OFFSET) & \
+                                                       LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_MASK)
 
 #endif /* __MX28_REGS_LCDIF_H__ */
index bd80ac77fc1e7307e88532dc0993cb4cff2a8471..4c8a2dae46f09939c9e67f66ac01723d632f4b00 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_ocotp_regs {
-       mxs_reg_32(hw_ocotp_ctrl)       /* 0x0 */
-       mxs_reg_32(hw_ocotp_data)       /* 0x10 */
-       mxs_reg_32(hw_ocotp_cust0)      /* 0x20 */
-       mxs_reg_32(hw_ocotp_cust1)      /* 0x30 */
-       mxs_reg_32(hw_ocotp_cust2)      /* 0x40 */
-       mxs_reg_32(hw_ocotp_cust3)      /* 0x50 */
-       mxs_reg_32(hw_ocotp_crypto0)    /* 0x60 */
-       mxs_reg_32(hw_ocotp_crypto1)    /* 0x70 */
-       mxs_reg_32(hw_ocotp_crypto2)    /* 0x80 */
-       mxs_reg_32(hw_ocotp_crypto3)    /* 0x90 */
-       mxs_reg_32(hw_ocotp_hwcap0)     /* 0xa0 */
-       mxs_reg_32(hw_ocotp_hwcap1)     /* 0xb0 */
-       mxs_reg_32(hw_ocotp_hwcap2)     /* 0xc0 */
-       mxs_reg_32(hw_ocotp_hwcap3)     /* 0xd0 */
-       mxs_reg_32(hw_ocotp_hwcap4)     /* 0xe0 */
-       mxs_reg_32(hw_ocotp_hwcap5)     /* 0xf0 */
-       mxs_reg_32(hw_ocotp_swcap)      /* 0x100 */
-       mxs_reg_32(hw_ocotp_custcap)    /* 0x110 */
-       mxs_reg_32(hw_ocotp_lock)       /* 0x120 */
-       mxs_reg_32(hw_ocotp_ops0)       /* 0x130 */
-       mxs_reg_32(hw_ocotp_ops1)       /* 0x140 */
-       mxs_reg_32(hw_ocotp_ops2)       /* 0x150 */
-       mxs_reg_32(hw_ocotp_ops3)       /* 0x160 */
-       mxs_reg_32(hw_ocotp_un0)        /* 0x170 */
-       mxs_reg_32(hw_ocotp_un1)        /* 0x180 */
-       mxs_reg_32(hw_ocotp_un2)        /* 0x190 */
-       mxs_reg_32(hw_ocotp_rom0)       /* 0x1a0 */
-       mxs_reg_32(hw_ocotp_rom1)       /* 0x1b0 */
-       mxs_reg_32(hw_ocotp_rom2)       /* 0x1c0 */
-       mxs_reg_32(hw_ocotp_rom3)       /* 0x1d0 */
-       mxs_reg_32(hw_ocotp_rom4)       /* 0x1e0 */
-       mxs_reg_32(hw_ocotp_rom5)       /* 0x1f0 */
-       mxs_reg_32(hw_ocotp_rom6)       /* 0x200 */
-       mxs_reg_32(hw_ocotp_rom7)       /* 0x210 */
-       mxs_reg_32(hw_ocotp_srk0)       /* 0x220 */
-       mxs_reg_32(hw_ocotp_srk1)       /* 0x230 */
-       mxs_reg_32(hw_ocotp_srk2)       /* 0x240 */
-       mxs_reg_32(hw_ocotp_srk3)       /* 0x250 */
-       mxs_reg_32(hw_ocotp_srk4)       /* 0x260 */
-       mxs_reg_32(hw_ocotp_srk5)       /* 0x270 */
-       mxs_reg_32(hw_ocotp_srk6)       /* 0x280 */
-       mxs_reg_32(hw_ocotp_srk7)       /* 0x290 */
-       mxs_reg_32(hw_ocotp_version)    /* 0x2a0 */
+       mxs_reg_32(hw_ocotp_ctrl);      /* 0x0 */
+       mxs_reg_32(hw_ocotp_data);      /* 0x10 */
+       mxs_reg_32(hw_ocotp_cust0);     /* 0x20 */
+       mxs_reg_32(hw_ocotp_cust1);     /* 0x30 */
+       mxs_reg_32(hw_ocotp_cust2);     /* 0x40 */
+       mxs_reg_32(hw_ocotp_cust3);     /* 0x50 */
+       mxs_reg_32(hw_ocotp_crypto0);   /* 0x60 */
+       mxs_reg_32(hw_ocotp_crypto1);   /* 0x70 */
+       mxs_reg_32(hw_ocotp_crypto2);   /* 0x80 */
+       mxs_reg_32(hw_ocotp_crypto3);   /* 0x90 */
+       mxs_reg_32(hw_ocotp_hwcap0);    /* 0xa0 */
+       mxs_reg_32(hw_ocotp_hwcap1);    /* 0xb0 */
+       mxs_reg_32(hw_ocotp_hwcap2);    /* 0xc0 */
+       mxs_reg_32(hw_ocotp_hwcap3);    /* 0xd0 */
+       mxs_reg_32(hw_ocotp_hwcap4);    /* 0xe0 */
+       mxs_reg_32(hw_ocotp_hwcap5);    /* 0xf0 */
+       mxs_reg_32(hw_ocotp_swcap);     /* 0x100 */
+       mxs_reg_32(hw_ocotp_custcap);   /* 0x110 */
+       mxs_reg_32(hw_ocotp_lock);      /* 0x120 */
+       mxs_reg_32(hw_ocotp_ops0);      /* 0x130 */
+       mxs_reg_32(hw_ocotp_ops1);      /* 0x140 */
+       mxs_reg_32(hw_ocotp_ops2);      /* 0x150 */
+       mxs_reg_32(hw_ocotp_ops3);      /* 0x160 */
+       mxs_reg_32(hw_ocotp_un0);       /* 0x170 */
+       mxs_reg_32(hw_ocotp_un1);       /* 0x180 */
+       mxs_reg_32(hw_ocotp_un2);       /* 0x190 */
+       mxs_reg_32(hw_ocotp_rom0);      /* 0x1a0 */
+       mxs_reg_32(hw_ocotp_rom1);      /* 0x1b0 */
+       mxs_reg_32(hw_ocotp_rom2);      /* 0x1c0 */
+       mxs_reg_32(hw_ocotp_rom3);      /* 0x1d0 */
+       mxs_reg_32(hw_ocotp_rom4);      /* 0x1e0 */
+       mxs_reg_32(hw_ocotp_rom5);      /* 0x1f0 */
+       mxs_reg_32(hw_ocotp_rom6);      /* 0x200 */
+       mxs_reg_32(hw_ocotp_rom7);      /* 0x210 */
+       mxs_reg_32(hw_ocotp_srk0);      /* 0x220 */
+       mxs_reg_32(hw_ocotp_srk1);      /* 0x230 */
+       mxs_reg_32(hw_ocotp_srk2);      /* 0x240 */
+       mxs_reg_32(hw_ocotp_srk3);      /* 0x250 */
+       mxs_reg_32(hw_ocotp_srk4);      /* 0x260 */
+       mxs_reg_32(hw_ocotp_srk5);      /* 0x270 */
+       mxs_reg_32(hw_ocotp_srk6);      /* 0x280 */
+       mxs_reg_32(hw_ocotp_srk7);      /* 0x290 */
+       mxs_reg_32(hw_ocotp_version);   /* 0x2a0 */
 };
 #endif
 
index 251fe6616d020e01cc69ee7a96089cfe5392bb65..6e6db1d4c6dada6ebcf409b96447816e1269dfde 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_pinctrl_regs {
-       mxs_reg_32(hw_pinctrl_ctrl)             /* 0x0 */
+       mxs_reg_32(hw_pinctrl_ctrl);            /* 0x0 */
 
        uint32_t        reserved1[60];
 
-       mxs_reg_32(hw_pinctrl_muxsel0)          /* 0x100 */
-       mxs_reg_32(hw_pinctrl_muxsel1)          /* 0x110 */
-       mxs_reg_32(hw_pinctrl_muxsel2)          /* 0x120 */
-       mxs_reg_32(hw_pinctrl_muxsel3)          /* 0x130 */
-       mxs_reg_32(hw_pinctrl_muxsel4)          /* 0x140 */
-       mxs_reg_32(hw_pinctrl_muxsel5)          /* 0x150 */
-       mxs_reg_32(hw_pinctrl_muxsel6)          /* 0x160 */
-       mxs_reg_32(hw_pinctrl_muxsel7)          /* 0x170 */
-       mxs_reg_32(hw_pinctrl_muxsel8)          /* 0x180 */
-       mxs_reg_32(hw_pinctrl_muxsel9)          /* 0x190 */
-       mxs_reg_32(hw_pinctrl_muxsel10) /* 0x1a0 */
-       mxs_reg_32(hw_pinctrl_muxsel11) /* 0x1b0 */
-       mxs_reg_32(hw_pinctrl_muxsel12) /* 0x1c0 */
-       mxs_reg_32(hw_pinctrl_muxsel13) /* 0x1d0 */
+       mxs_reg_32(hw_pinctrl_muxsel0);         /* 0x100 */
+       mxs_reg_32(hw_pinctrl_muxsel1);         /* 0x110 */
+       mxs_reg_32(hw_pinctrl_muxsel2);         /* 0x120 */
+       mxs_reg_32(hw_pinctrl_muxsel3);         /* 0x130 */
+       mxs_reg_32(hw_pinctrl_muxsel4);         /* 0x140 */
+       mxs_reg_32(hw_pinctrl_muxsel5);         /* 0x150 */
+       mxs_reg_32(hw_pinctrl_muxsel6);         /* 0x160 */
+       mxs_reg_32(hw_pinctrl_muxsel7);         /* 0x170 */
+       mxs_reg_32(hw_pinctrl_muxsel8);         /* 0x180 */
+       mxs_reg_32(hw_pinctrl_muxsel9);         /* 0x190 */
+       mxs_reg_32(hw_pinctrl_muxsel10);        /* 0x1a0 */
+       mxs_reg_32(hw_pinctrl_muxsel11);        /* 0x1b0 */
+       mxs_reg_32(hw_pinctrl_muxsel12);        /* 0x1c0 */
+       mxs_reg_32(hw_pinctrl_muxsel13);        /* 0x1d0 */
 
        uint32_t        reserved2[72];
 
-       mxs_reg_32(hw_pinctrl_drive0)           /* 0x300 */
-       mxs_reg_32(hw_pinctrl_drive1)           /* 0x310 */
-       mxs_reg_32(hw_pinctrl_drive2)           /* 0x320 */
-       mxs_reg_32(hw_pinctrl_drive3)           /* 0x330 */
-       mxs_reg_32(hw_pinctrl_drive4)           /* 0x340 */
-       mxs_reg_32(hw_pinctrl_drive5)           /* 0x350 */
-       mxs_reg_32(hw_pinctrl_drive6)           /* 0x360 */
-       mxs_reg_32(hw_pinctrl_drive7)           /* 0x370 */
-       mxs_reg_32(hw_pinctrl_drive8)           /* 0x380 */
-       mxs_reg_32(hw_pinctrl_drive9)           /* 0x390 */
-       mxs_reg_32(hw_pinctrl_drive10)          /* 0x3a0 */
-       mxs_reg_32(hw_pinctrl_drive11)          /* 0x3b0 */
-       mxs_reg_32(hw_pinctrl_drive12)          /* 0x3c0 */
-       mxs_reg_32(hw_pinctrl_drive13)          /* 0x3d0 */
-       mxs_reg_32(hw_pinctrl_drive14)          /* 0x3e0 */
-       mxs_reg_32(hw_pinctrl_drive15)          /* 0x3f0 */
-       mxs_reg_32(hw_pinctrl_drive16)          /* 0x400 */
-       mxs_reg_32(hw_pinctrl_drive17)          /* 0x410 */
-       mxs_reg_32(hw_pinctrl_drive18)          /* 0x420 */
-       mxs_reg_32(hw_pinctrl_drive19)          /* 0x430 */
+       mxs_reg_32(hw_pinctrl_drive0);          /* 0x300 */
+       mxs_reg_32(hw_pinctrl_drive1);          /* 0x310 */
+       mxs_reg_32(hw_pinctrl_drive2);          /* 0x320 */
+       mxs_reg_32(hw_pinctrl_drive3);          /* 0x330 */
+       mxs_reg_32(hw_pinctrl_drive4);          /* 0x340 */
+       mxs_reg_32(hw_pinctrl_drive5);          /* 0x350 */
+       mxs_reg_32(hw_pinctrl_drive6);          /* 0x360 */
+       mxs_reg_32(hw_pinctrl_drive7);          /* 0x370 */
+       mxs_reg_32(hw_pinctrl_drive8);          /* 0x380 */
+       mxs_reg_32(hw_pinctrl_drive9);          /* 0x390 */
+       mxs_reg_32(hw_pinctrl_drive10);         /* 0x3a0 */
+       mxs_reg_32(hw_pinctrl_drive11);         /* 0x3b0 */
+       mxs_reg_32(hw_pinctrl_drive12);         /* 0x3c0 */
+       mxs_reg_32(hw_pinctrl_drive13);         /* 0x3d0 */
+       mxs_reg_32(hw_pinctrl_drive14);         /* 0x3e0 */
+       mxs_reg_32(hw_pinctrl_drive15);         /* 0x3f0 */
+       mxs_reg_32(hw_pinctrl_drive16);         /* 0x400 */
+       mxs_reg_32(hw_pinctrl_drive17);         /* 0x410 */
+       mxs_reg_32(hw_pinctrl_drive18);         /* 0x420 */
+       mxs_reg_32(hw_pinctrl_drive19);         /* 0x430 */
 
        uint32_t        reserved3[112];
 
-       mxs_reg_32(hw_pinctrl_pull0)            /* 0x600 */
-       mxs_reg_32(hw_pinctrl_pull1)            /* 0x610 */
-       mxs_reg_32(hw_pinctrl_pull2)            /* 0x620 */
-       mxs_reg_32(hw_pinctrl_pull3)            /* 0x630 */
-       mxs_reg_32(hw_pinctrl_pull4)            /* 0x640 */
-       mxs_reg_32(hw_pinctrl_pull5)            /* 0x650 */
-       mxs_reg_32(hw_pinctrl_pull6)            /* 0x660 */
+       mxs_reg_32(hw_pinctrl_pull0);           /* 0x600 */
+       mxs_reg_32(hw_pinctrl_pull1);           /* 0x610 */
+       mxs_reg_32(hw_pinctrl_pull2);           /* 0x620 */
+       mxs_reg_32(hw_pinctrl_pull3);           /* 0x630 */
+       mxs_reg_32(hw_pinctrl_pull4);           /* 0x640 */
+       mxs_reg_32(hw_pinctrl_pull5);           /* 0x650 */
+       mxs_reg_32(hw_pinctrl_pull6);           /* 0x660 */
 
        uint32_t        reserved4[36];
 
-       mxs_reg_32(hw_pinctrl_dout0)            /* 0x700 */
-       mxs_reg_32(hw_pinctrl_dout1)            /* 0x710 */
-       mxs_reg_32(hw_pinctrl_dout2)            /* 0x720 */
-       mxs_reg_32(hw_pinctrl_dout3)            /* 0x730 */
-       mxs_reg_32(hw_pinctrl_dout4)            /* 0x740 */
+       mxs_reg_32(hw_pinctrl_dout0);           /* 0x700 */
+       mxs_reg_32(hw_pinctrl_dout1);           /* 0x710 */
+       mxs_reg_32(hw_pinctrl_dout2);           /* 0x720 */
+       mxs_reg_32(hw_pinctrl_dout3);           /* 0x730 */
+       mxs_reg_32(hw_pinctrl_dout4);           /* 0x740 */
 
        uint32_t        reserved5[108];
 
-       mxs_reg_32(hw_pinctrl_din0)             /* 0x900 */
-       mxs_reg_32(hw_pinctrl_din1)             /* 0x910 */
-       mxs_reg_32(hw_pinctrl_din2)             /* 0x920 */
-       mxs_reg_32(hw_pinctrl_din3)             /* 0x930 */
-       mxs_reg_32(hw_pinctrl_din4)             /* 0x940 */
+       mxs_reg_32(hw_pinctrl_din0);            /* 0x900 */
+       mxs_reg_32(hw_pinctrl_din1);            /* 0x910 */
+       mxs_reg_32(hw_pinctrl_din2);            /* 0x920 */
+       mxs_reg_32(hw_pinctrl_din3);            /* 0x930 */
+       mxs_reg_32(hw_pinctrl_din4);            /* 0x940 */
 
        uint32_t        reserved6[108];
 
-       mxs_reg_32(hw_pinctrl_doe0)             /* 0xb00 */
-       mxs_reg_32(hw_pinctrl_doe1)             /* 0xb10 */
-       mxs_reg_32(hw_pinctrl_doe2)             /* 0xb20 */
-       mxs_reg_32(hw_pinctrl_doe3)             /* 0xb30 */
-       mxs_reg_32(hw_pinctrl_doe4)             /* 0xb40 */
+       mxs_reg_32(hw_pinctrl_doe0);            /* 0xb00 */
+       mxs_reg_32(hw_pinctrl_doe1);            /* 0xb10 */
+       mxs_reg_32(hw_pinctrl_doe2);            /* 0xb20 */
+       mxs_reg_32(hw_pinctrl_doe3);            /* 0xb30 */
+       mxs_reg_32(hw_pinctrl_doe4);            /* 0xb40 */
 
        uint32_t        reserved7[300];
 
-       mxs_reg_32(hw_pinctrl_pin2irq0) /* 0x1000 */
-       mxs_reg_32(hw_pinctrl_pin2irq1) /* 0x1010 */
-       mxs_reg_32(hw_pinctrl_pin2irq2) /* 0x1020 */
-       mxs_reg_32(hw_pinctrl_pin2irq3) /* 0x1030 */
-       mxs_reg_32(hw_pinctrl_pin2irq4) /* 0x1040 */
+       mxs_reg_32(hw_pinctrl_pin2irq0);        /* 0x1000 */
+       mxs_reg_32(hw_pinctrl_pin2irq1);        /* 0x1010 */
+       mxs_reg_32(hw_pinctrl_pin2irq2);        /* 0x1020 */
+       mxs_reg_32(hw_pinctrl_pin2irq3);        /* 0x1030 */
+       mxs_reg_32(hw_pinctrl_pin2irq4);        /* 0x1040 */
 
        uint32_t        reserved8[44];
 
-       mxs_reg_32(hw_pinctrl_irqen0)           /* 0x1100 */
-       mxs_reg_32(hw_pinctrl_irqen1)           /* 0x1110 */
-       mxs_reg_32(hw_pinctrl_irqen2)           /* 0x1120 */
-       mxs_reg_32(hw_pinctrl_irqen3)           /* 0x1130 */
-       mxs_reg_32(hw_pinctrl_irqen4)           /* 0x1140 */
+       mxs_reg_32(hw_pinctrl_irqen0);          /* 0x1100 */
+       mxs_reg_32(hw_pinctrl_irqen1);          /* 0x1110 */
+       mxs_reg_32(hw_pinctrl_irqen2);          /* 0x1120 */
+       mxs_reg_32(hw_pinctrl_irqen3);          /* 0x1130 */
+       mxs_reg_32(hw_pinctrl_irqen4);          /* 0x1140 */
 
        uint32_t        reserved9[44];
 
-       mxs_reg_32(hw_pinctrl_irqlevel0)        /* 0x1200 */
-       mxs_reg_32(hw_pinctrl_irqlevel1)        /* 0x1210 */
-       mxs_reg_32(hw_pinctrl_irqlevel2)        /* 0x1220 */
-       mxs_reg_32(hw_pinctrl_irqlevel3)        /* 0x1230 */
-       mxs_reg_32(hw_pinctrl_irqlevel4)        /* 0x1240 */
+       mxs_reg_32(hw_pinctrl_irqlevel0);       /* 0x1200 */
+       mxs_reg_32(hw_pinctrl_irqlevel1);       /* 0x1210 */
+       mxs_reg_32(hw_pinctrl_irqlevel2);       /* 0x1220 */
+       mxs_reg_32(hw_pinctrl_irqlevel3);       /* 0x1230 */
+       mxs_reg_32(hw_pinctrl_irqlevel4);       /* 0x1240 */
 
        uint32_t        reserved10[44];
 
-       mxs_reg_32(hw_pinctrl_irqpol0)          /* 0x1300 */
-       mxs_reg_32(hw_pinctrl_irqpol1)          /* 0x1310 */
-       mxs_reg_32(hw_pinctrl_irqpol2)          /* 0x1320 */
-       mxs_reg_32(hw_pinctrl_irqpol3)          /* 0x1330 */
-       mxs_reg_32(hw_pinctrl_irqpol4)          /* 0x1340 */
+       mxs_reg_32(hw_pinctrl_irqpol0);         /* 0x1300 */
+       mxs_reg_32(hw_pinctrl_irqpol1);         /* 0x1310 */
+       mxs_reg_32(hw_pinctrl_irqpol2);         /* 0x1320 */
+       mxs_reg_32(hw_pinctrl_irqpol3);         /* 0x1330 */
+       mxs_reg_32(hw_pinctrl_irqpol4);         /* 0x1340 */
 
        uint32_t        reserved11[44];
 
-       mxs_reg_32(hw_pinctrl_irqstat0) /* 0x1400 */
-       mxs_reg_32(hw_pinctrl_irqstat1) /* 0x1410 */
-       mxs_reg_32(hw_pinctrl_irqstat2) /* 0x1420 */
-       mxs_reg_32(hw_pinctrl_irqstat3) /* 0x1430 */
-       mxs_reg_32(hw_pinctrl_irqstat4) /* 0x1440 */
+       mxs_reg_32(hw_pinctrl_irqstat0);        /* 0x1400 */
+       mxs_reg_32(hw_pinctrl_irqstat1);        /* 0x1410 */
+       mxs_reg_32(hw_pinctrl_irqstat2);        /* 0x1420 */
+       mxs_reg_32(hw_pinctrl_irqstat3);        /* 0x1430 */
+       mxs_reg_32(hw_pinctrl_irqstat4);        /* 0x1440 */
 
        uint32_t        reserved12[380];
 
-       mxs_reg_32(hw_pinctrl_emi_odt_ctrl)     /* 0x1a40 */
+       mxs_reg_32(hw_pinctrl_emi_odt_ctrl);    /* 0x1a40 */
 
        uint32_t        reserved13[76];
 
-       mxs_reg_32(hw_pinctrl_emi_ds_ctrl)      /* 0x1b80 */
+       mxs_reg_32(hw_pinctrl_emi_ds_ctrl);     /* 0x1b80 */
 };
 #endif
 
index 9528e3ce9ad805ec30a1c0595924dbddb296c50f..f24d99da66773eb96fd25e591b75db3c83f93a06 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_power_regs {
-       mxs_reg_32(hw_power_ctrl)
-       mxs_reg_32(hw_power_5vctrl)
-       mxs_reg_32(hw_power_minpwr)
-       mxs_reg_32(hw_power_charge)
-       uint32_t        hw_power_vdddctrl;
-       uint32_t        reserved_vddd[3];
-       uint32_t        hw_power_vddactrl;
-       uint32_t        reserved_vdda[3];
-       uint32_t        hw_power_vddioctrl;
-       uint32_t        reserved_vddio[3];
-       uint32_t        hw_power_vddmemctrl;
-       uint32_t        reserved_vddmem[3];
-       uint32_t        hw_power_dcdc4p2;
-       uint32_t        reserved_dcdc4p2[3];
-       uint32_t        hw_power_misc;
-       uint32_t        reserved_misc[3];
-       uint32_t        hw_power_dclimits;
-       uint32_t        reserved_dclimits[3];
-       mxs_reg_32(hw_power_loopctrl)
-       uint32_t        hw_power_sts;
-       uint32_t        reserved_sts[3];
-       mxs_reg_32(hw_power_speed)
-       uint32_t        hw_power_battmonitor;
-       uint32_t        reserved_battmonitor[3];
+       mxs_reg_32(hw_power_ctrl);              /* 0x00 */
+       mxs_reg_32(hw_power_5vctrl);            /* 0x10 */
+       mxs_reg_32(hw_power_minpwr);            /* 0x20 */
+       mxs_reg_32(hw_power_charge);            /* 0x30 */
+       reg_32(hw_power_vdddctrl);              /* 0x40 */
+       reg_32(hw_power_vddactrl);              /* 0x50 */
+       reg_32(hw_power_vddioctrl);             /* 0x60 */
+       reg_32(hw_power_vddmemctrl);            /* 0x70 */
+       reg_32(hw_power_dcdc4p2);               /* 0x80 */
+       reg_32(hw_power_misc);                  /* 0x90 */
+       reg_32(hw_power_dclimits);              /* 0xa0 */
+       mxs_reg_32(hw_power_loopctrl);          /* 0xb0 */
+       reg_32(hw_power_sts);                   /* 0xc0 */
+       mxs_reg_32(hw_power_speed);             /* 0xd0 */
+       reg_32(hw_power_battmonitor);           /* 0xe0 */
 
-       uint32_t        reserved[4];
+       reg_32(reserved);                       /* 0xf0 */
 
-       mxs_reg_32(hw_power_reset)
-       mxs_reg_32(hw_power_debug)
-       mxs_reg_32(hw_power_thermal)
-       mxs_reg_32(hw_power_usb1ctrl)
-       mxs_reg_32(hw_power_special)
-       mxs_reg_32(hw_power_version)
-       mxs_reg_32(hw_power_anaclkctrl)
-       mxs_reg_32(hw_power_refctrl)
+       mxs_reg_32(hw_power_reset);             /* 0x100 */
+       mxs_reg_32(hw_power_debug);             /* 0x110 */
+       mxs_reg_32(hw_power_thermal);           /* 0x120 */
+       mxs_reg_32(hw_power_usb1ctrl);          /* 0x130 */
+       mxs_reg_32(hw_power_special);           /* 0x140 */
+       mxs_reg_32(hw_power_version);           /* 0x150 */
+       mxs_reg_32(hw_power_anaclkctrl);        /* 0x160 */
+       mxs_reg_32(hw_power_refctrl);           /* 0x170 */
 };
 #endif
 
@@ -348,7 +339,8 @@ struct mxs_power_regs {
 #define        POWER_THERMAL_PWD                               (1 << 7)
 #define        POWER_THERMAL_LOW_POWER                         (1 << 6)
 #define        POWER_THERMAL_OFFSET_ADJ_MASK                   (0x3 << 4)
-#define        POWER_THERMAL_OFFSET_ADJ_OFFSET                 4
+#define        POWER_THERMAL_OFFSET_ADJ_OFFSET(n)              (((n) << 4) &   \
+                                               POWER_THERMAL_OFFSET_ADJ_MASK)
 #define        POWER_THERMAL_OFFSET_ADJ_ENABLE                 (1 << 3)
 #define        POWER_THERMAL_TEMP_THRESHOLD_MASK               0x7
 #define        POWER_THERMAL_TEMP_THRESHOLD_OFFSET             0
index 03e2e5dd62881cc7cc3b20a1b6731abd8d644c7a..8d3eccfb75417e59fcf552b9d068c08bf9f2d595 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_rtc_regs {
-       mxs_reg_32(hw_rtc_ctrl)
-       mxs_reg_32(hw_rtc_stat)
-       mxs_reg_32(hw_rtc_milliseconds)
-       mxs_reg_32(hw_rtc_seconds)
-       mxs_reg_32(hw_rtc_rtc_alarm)
-       mxs_reg_32(hw_rtc_watchdog)
-       mxs_reg_32(hw_rtc_persistent0)
-       mxs_reg_32(hw_rtc_persistent1)
-       mxs_reg_32(hw_rtc_persistent2)
-       mxs_reg_32(hw_rtc_persistent3)
-       mxs_reg_32(hw_rtc_persistent4)
-       mxs_reg_32(hw_rtc_persistent5)
-       mxs_reg_32(hw_rtc_debug)
-       mxs_reg_32(hw_rtc_version)
+       mxs_reg_32(hw_rtc_ctrl);
+       mxs_reg_32(hw_rtc_stat);
+       mxs_reg_32(hw_rtc_milliseconds);
+       mxs_reg_32(hw_rtc_seconds);
+       mxs_reg_32(hw_rtc_rtc_alarm);
+       mxs_reg_32(hw_rtc_watchdog);
+       mxs_reg_32(hw_rtc_persistent0);
+       mxs_reg_32(hw_rtc_persistent1);
+       mxs_reg_32(hw_rtc_persistent2);
+       mxs_reg_32(hw_rtc_persistent3);
+       mxs_reg_32(hw_rtc_persistent4);
+       mxs_reg_32(hw_rtc_persistent5);
+       mxs_reg_32(hw_rtc_debug);
+       mxs_reg_32(hw_rtc_version);
 };
 #endif
 
@@ -46,8 +46,24 @@ struct mxs_rtc_regs {
 #define        RTC_STAT_WATCHDOG_PRESENT               (1 << 29)
 #define        RTC_STAT_XTAL32000_PRESENT              (1 << 28)
 #define        RTC_STAT_XTAL32768_PRESENT              (1 << 27)
+#define RTC_STAT_STALE_REGS_SECONDS            (1 << 23)
+#define RTC_STAT_STALE_REGS_ALARM              (1 << 22)
+#define RTC_STAT_STALE_REGS_PERSISTENT5                (1 << 21)
+#define RTC_STAT_STALE_REGS_PERSISTENT4                (1 << 20)
+#define RTC_STAT_STALE_REGS_PERSISTENT3                (1 << 19)
+#define RTC_STAT_STALE_REGS_PERSISTENT2                (1 << 18)
+#define RTC_STAT_STALE_REGS_PERSISTENT1                (1 << 17)
+#define RTC_STAT_STALE_REGS_PERSISTENT0                (1 << 16)
 #define        RTC_STAT_STALE_REGS_MASK                (0xff << 16)
 #define        RTC_STAT_STALE_REGS_OFFSET              16
+#define RTC_STAT_NEW_REGS_SECONDS              (1 << 15)
+#define RTC_STAT_NEW_REGS_ALARM                        (1 << 14)
+#define RTC_STAT_NEW_REGS_PERSISTENT5          (1 << 13)
+#define RTC_STAT_NEW_REGS_PERSISTENT4          (1 << 12)
+#define RTC_STAT_NEW_REGS_PERSISTENT3          (1 << 11)
+#define RTC_STAT_NEW_REGS_PERSISTENT2          (1 << 10)
+#define RTC_STAT_NEW_REGS_PERSISTENT1          (1 << 9)
+#define RTC_STAT_NEW_REGS_PERSISTENT0          (1 << 8)
 #define        RTC_STAT_NEW_REGS_MASK                  (0xff << 8)
 #define        RTC_STAT_NEW_REGS_OFFSET                8
 
index e991216d0bd4bda0bbed9bbb8421027af67a122c..464e9e0914b6f4d02cd8502499c3fbda1af4b13d 100644 (file)
 #ifndef        __ASSEMBLY__
 #if defined(CONFIG_MX23)
 struct mxs_ssp_regs {
-       mxs_reg_32(hw_ssp_ctrl0)
-       mxs_reg_32(hw_ssp_cmd0)
-       mxs_reg_32(hw_ssp_cmd1)
-       mxs_reg_32(hw_ssp_compref)
-       mxs_reg_32(hw_ssp_compmask)
-       mxs_reg_32(hw_ssp_timing)
-       mxs_reg_32(hw_ssp_ctrl1)
-       mxs_reg_32(hw_ssp_data)
-       mxs_reg_32(hw_ssp_sdresp0)
-       mxs_reg_32(hw_ssp_sdresp1)
-       mxs_reg_32(hw_ssp_sdresp2)
-       mxs_reg_32(hw_ssp_sdresp3)
-       mxs_reg_32(hw_ssp_status)
-
-       uint32_t        reserved1[12];
-
-       mxs_reg_32(hw_ssp_debug)
-       mxs_reg_32(hw_ssp_version)
+       mxs_reg_32(hw_ssp_ctrl0);
+       mxs_reg_32(hw_ssp_cmd0);
+       mxs_reg_32(hw_ssp_cmd1);
+       mxs_reg_32(hw_ssp_compref);
+       mxs_reg_32(hw_ssp_compmask);
+       mxs_reg_32(hw_ssp_timing);
+       mxs_reg_32(hw_ssp_ctrl1);
+       mxs_reg_32(hw_ssp_data);
+       mxs_reg_32(hw_ssp_sdresp0);
+       mxs_reg_32(hw_ssp_sdresp1);
+       mxs_reg_32(hw_ssp_sdresp2);
+       mxs_reg_32(hw_ssp_sdresp3);
+       mxs_reg_32(hw_ssp_status);
+       reg_32(reserved[3]);
+       mxs_reg_32(hw_ssp_debug);
+       mxs_reg_32(hw_ssp_version);
 };
 #elif defined(CONFIG_MX28)
 struct mxs_ssp_regs {
-       mxs_reg_32(hw_ssp_ctrl0)
-       mxs_reg_32(hw_ssp_cmd0)
-       mxs_reg_32(hw_ssp_cmd1)
-       mxs_reg_32(hw_ssp_xfer_size)
-       mxs_reg_32(hw_ssp_block_size)
-       mxs_reg_32(hw_ssp_compref)
-       mxs_reg_32(hw_ssp_compmask)
-       mxs_reg_32(hw_ssp_timing)
-       mxs_reg_32(hw_ssp_ctrl1)
-       mxs_reg_32(hw_ssp_data)
-       mxs_reg_32(hw_ssp_sdresp0)
-       mxs_reg_32(hw_ssp_sdresp1)
-       mxs_reg_32(hw_ssp_sdresp2)
-       mxs_reg_32(hw_ssp_sdresp3)
-       mxs_reg_32(hw_ssp_ddr_ctrl)
-       mxs_reg_32(hw_ssp_dll_ctrl)
-       mxs_reg_32(hw_ssp_status)
-       mxs_reg_32(hw_ssp_dll_sts)
-       mxs_reg_32(hw_ssp_debug)
-       mxs_reg_32(hw_ssp_version)
+       mxs_reg_32(hw_ssp_ctrl0);
+       mxs_reg_32(hw_ssp_cmd0);
+       mxs_reg_32(hw_ssp_cmd1);
+       mxs_reg_32(hw_ssp_xfer_size);
+       mxs_reg_32(hw_ssp_block_size);
+       mxs_reg_32(hw_ssp_compref);
+       mxs_reg_32(hw_ssp_compmask);
+       mxs_reg_32(hw_ssp_timing);
+       mxs_reg_32(hw_ssp_ctrl1);
+       mxs_reg_32(hw_ssp_data);
+       mxs_reg_32(hw_ssp_sdresp0);
+       mxs_reg_32(hw_ssp_sdresp1);
+       mxs_reg_32(hw_ssp_sdresp2);
+       mxs_reg_32(hw_ssp_sdresp3);
+       mxs_reg_32(hw_ssp_ddr_ctrl);
+       mxs_reg_32(hw_ssp_dll_ctrl);
+       mxs_reg_32(hw_ssp_status);
+       mxs_reg_32(hw_ssp_dll_sts);
+       mxs_reg_32(hw_ssp_debug);
+       mxs_reg_32(hw_ssp_version);
 };
 #endif
 
index 713c630dcc3e3199ff029f3e2eee675ab1a3e2d6..0ee3ec81bb7818baf41be1c01a14c2514f93bda5 100644 (file)
 
 #ifndef        __ASSEMBLY__
 struct mxs_timrot_regs {
-       mxs_reg_32(hw_timrot_rotctrl)
-       mxs_reg_32(hw_timrot_rotcount)
+       mxs_reg_32(hw_timrot_rotctrl);
+       mxs_reg_32(hw_timrot_rotcount);
 #if defined(CONFIG_MX23)
-       mxs_reg_32(hw_timrot_timctrl0)
-       mxs_reg_32(hw_timrot_timcount0)
-       mxs_reg_32(hw_timrot_timctrl1)
-       mxs_reg_32(hw_timrot_timcount1)
-       mxs_reg_32(hw_timrot_timctrl2)
-       mxs_reg_32(hw_timrot_timcount2)
-       mxs_reg_32(hw_timrot_timctrl3)
-       mxs_reg_32(hw_timrot_timcount3)
+       mxs_reg_32(hw_timrot_timctrl0);
+       mxs_reg_32(hw_timrot_timcount0);
+       mxs_reg_32(hw_timrot_timctrl1);
+       mxs_reg_32(hw_timrot_timcount1);
+       mxs_reg_32(hw_timrot_timctrl2);
+       mxs_reg_32(hw_timrot_timcount2);
+       mxs_reg_32(hw_timrot_timctrl3);
+       mxs_reg_32(hw_timrot_timcount3);
 #elif defined(CONFIG_MX28)
-       mxs_reg_32(hw_timrot_timctrl0)
-       mxs_reg_32(hw_timrot_running_count0)
-       mxs_reg_32(hw_timrot_fixed_count0)
-       mxs_reg_32(hw_timrot_match_count0)
-       mxs_reg_32(hw_timrot_timctrl1)
-       mxs_reg_32(hw_timrot_running_count1)
-       mxs_reg_32(hw_timrot_fixed_count1)
-       mxs_reg_32(hw_timrot_match_count1)
-       mxs_reg_32(hw_timrot_timctrl2)
-       mxs_reg_32(hw_timrot_running_count2)
-       mxs_reg_32(hw_timrot_fixed_count2)
-       mxs_reg_32(hw_timrot_match_count2)
-       mxs_reg_32(hw_timrot_timctrl3)
-       mxs_reg_32(hw_timrot_running_count3)
-       mxs_reg_32(hw_timrot_fixed_count3)
-       mxs_reg_32(hw_timrot_match_count3)
+       mxs_reg_32(hw_timrot_timctrl0);
+       mxs_reg_32(hw_timrot_running_count0);
+       mxs_reg_32(hw_timrot_fixed_count0);
+       mxs_reg_32(hw_timrot_match_count0);
+       mxs_reg_32(hw_timrot_timctrl1);
+       mxs_reg_32(hw_timrot_running_count1);
+       mxs_reg_32(hw_timrot_fixed_count1);
+       mxs_reg_32(hw_timrot_match_count1);
+       mxs_reg_32(hw_timrot_timctrl2);
+       mxs_reg_32(hw_timrot_running_count2);
+       mxs_reg_32(hw_timrot_fixed_count2);
+       mxs_reg_32(hw_timrot_match_count2);
+       mxs_reg_32(hw_timrot_timctrl3);
+       mxs_reg_32(hw_timrot_running_count3);
+       mxs_reg_32(hw_timrot_fixed_count3);
+       mxs_reg_32(hw_timrot_match_count3);
 #endif
-       mxs_reg_32(hw_timrot_version)
+       mxs_reg_32(hw_timrot_version);
 };
 #endif
 
index eabefc6448a98ee04ef924d7b4a25cc92432173c..bf110a5e0e74b2397fb30823588b1a5554394e4f 100644 (file)
 #define __REGS_USBPHY_H__
 
 struct mxs_usbphy_regs {
-       mxs_reg_32(hw_usbphy_pwd)
-       mxs_reg_32(hw_usbphy_tx)
-       mxs_reg_32(hw_usbphy_rx)
-       mxs_reg_32(hw_usbphy_ctrl)
-       mxs_reg_32(hw_usbphy_status)
-       mxs_reg_32(hw_usbphy_debug)
-       mxs_reg_32(hw_usbphy_debug0_status)
-       mxs_reg_32(hw_usbphy_debug1)
-       mxs_reg_32(hw_usbphy_version)
-       mxs_reg_32(hw_usbphy_ip)
+       mxs_reg_32(hw_usbphy_pwd);
+       mxs_reg_32(hw_usbphy_tx);
+       mxs_reg_32(hw_usbphy_rx);
+       mxs_reg_32(hw_usbphy_ctrl);
+       mxs_reg_32(hw_usbphy_status);
+       mxs_reg_32(hw_usbphy_debug);
+       mxs_reg_32(hw_usbphy_debug0_status);
+       mxs_reg_32(hw_usbphy_debug1);
+       mxs_reg_32(hw_usbphy_version);
+       mxs_reg_32(hw_usbphy_ip);
 };
 
 #define        USBPHY_PWD_RXPWDRX                              (1 << 20)
index 062f3de1d05bfd4de1011762b55fbb6311c84fc9..407055c9095f170d965f867b980e18d728c63eda 100644 (file)
@@ -22,6 +22,8 @@ int mxs_wait_mask_clr(struct mxs_register_32 *reg,
 
 int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int));
 
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
+
 #ifdef CONFIG_SPL_BUILD
 
 #if defined(CONFIG_MX23)
index 342f045f41419471adea238aed0fcb309e7185d2..72b6733c9a3aa68e62784632bcfff2d0bf03ced8 100644 (file)
 
 /* Reg mapping structure */
 struct emif_reg_struct {
-       u32 emif_mod_id_rev;
-       u32 emif_status;
-       u32 emif_sdram_config;
-       u32 emif_lpddr2_nvm_config;
-       u32 emif_sdram_ref_ctrl;
-       u32 emif_sdram_ref_ctrl_shdw;
-       u32 emif_sdram_tim_1;
-       u32 emif_sdram_tim_1_shdw;
-       u32 emif_sdram_tim_2;
-       u32 emif_sdram_tim_2_shdw;
-       u32 emif_sdram_tim_3;
-       u32 emif_sdram_tim_3_shdw;
-       u32 emif_lpddr2_nvm_tim;
-       u32 emif_lpddr2_nvm_tim_shdw;
-       u32 emif_pwr_mgmt_ctrl;
-       u32 emif_pwr_mgmt_ctrl_shdw;
-       u32 emif_lpddr2_mode_reg_data;
-       u32 padding1[1];
-       u32 emif_lpddr2_mode_reg_data_es2;
-       u32 padding11[1];
-       u32 emif_lpddr2_mode_reg_cfg;
-       u32 emif_l3_config;
-       u32 emif_l3_cfg_val_1;
-       u32 emif_l3_cfg_val_2;
-       u32 emif_iodft_tlgc;
-       u32 padding2[7];
-       u32 emif_perf_cnt_1;
-       u32 emif_perf_cnt_2;
-       u32 emif_perf_cnt_cfg;
-       u32 emif_perf_cnt_sel;
-       u32 emif_perf_cnt_tim;
-       u32 padding3;
-       u32 emif_read_idlectrl;
-       u32 emif_read_idlectrl_shdw;
-       u32 padding4;
-       u32 emif_irqstatus_raw_sys;
-       u32 emif_irqstatus_raw_ll;
-       u32 emif_irqstatus_sys;
-       u32 emif_irqstatus_ll;
-       u32 emif_irqenable_set_sys;
-       u32 emif_irqenable_set_ll;
-       u32 emif_irqenable_clr_sys;
-       u32 emif_irqenable_clr_ll;
-       u32 padding5;
-       u32 emif_zq_config;
-       u32 emif_temp_alert_config;
-       u32 emif_l3_err_log;
-       u32 emif_rd_wr_lvl_rmp_win;
-       u32 emif_rd_wr_lvl_rmp_ctl;
-       u32 emif_rd_wr_lvl_ctl;
-       u32 padding6[1];
-       u32 emif_ddr_phy_ctrl_1;
-       u32 emif_ddr_phy_ctrl_1_shdw;
-       u32 emif_ddr_phy_ctrl_2;
-       u32 padding7[4];
-       u32 emif_prio_class_serv_map;
-       u32 emif_connect_id_serv_1_map;
-       u32 emif_connect_id_serv_2_map;
-       u32 padding8[5];
-       u32 emif_rd_wr_exec_thresh;
-       u32 emif_cos_config;
-       u32 padding9[6];
-       u32 emif_ddr_phy_status[28];
-       u32 padding10[20];
-       u32 emif_ddr_ext_phy_ctrl_1;
-       u32 emif_ddr_ext_phy_ctrl_1_shdw;
-       u32 emif_ddr_ext_phy_ctrl_2;
-       u32 emif_ddr_ext_phy_ctrl_2_shdw;
-       u32 emif_ddr_ext_phy_ctrl_3;
-       u32 emif_ddr_ext_phy_ctrl_3_shdw;
-       u32 emif_ddr_ext_phy_ctrl_4;
-       u32 emif_ddr_ext_phy_ctrl_4_shdw;
-       u32 emif_ddr_ext_phy_ctrl_5;
-       u32 emif_ddr_ext_phy_ctrl_5_shdw;
-       u32 emif_ddr_ext_phy_ctrl_6;
-       u32 emif_ddr_ext_phy_ctrl_6_shdw;
-       u32 emif_ddr_ext_phy_ctrl_7;
-       u32 emif_ddr_ext_phy_ctrl_7_shdw;
-       u32 emif_ddr_ext_phy_ctrl_8;
-       u32 emif_ddr_ext_phy_ctrl_8_shdw;
-       u32 emif_ddr_ext_phy_ctrl_9;
-       u32 emif_ddr_ext_phy_ctrl_9_shdw;
-       u32 emif_ddr_ext_phy_ctrl_10;
-       u32 emif_ddr_ext_phy_ctrl_10_shdw;
-       u32 emif_ddr_ext_phy_ctrl_11;
-       u32 emif_ddr_ext_phy_ctrl_11_shdw;
-       u32 emif_ddr_ext_phy_ctrl_12;
-       u32 emif_ddr_ext_phy_ctrl_12_shdw;
-       u32 emif_ddr_ext_phy_ctrl_13;
-       u32 emif_ddr_ext_phy_ctrl_13_shdw;
-       u32 emif_ddr_ext_phy_ctrl_14;
-       u32 emif_ddr_ext_phy_ctrl_14_shdw;
-       u32 emif_ddr_ext_phy_ctrl_15;
-       u32 emif_ddr_ext_phy_ctrl_15_shdw;
-       u32 emif_ddr_ext_phy_ctrl_16;
-       u32 emif_ddr_ext_phy_ctrl_16_shdw;
-       u32 emif_ddr_ext_phy_ctrl_17;
-       u32 emif_ddr_ext_phy_ctrl_17_shdw;
-       u32 emif_ddr_ext_phy_ctrl_18;
-       u32 emif_ddr_ext_phy_ctrl_18_shdw;
-       u32 emif_ddr_ext_phy_ctrl_19;
-       u32 emif_ddr_ext_phy_ctrl_19_shdw;
-       u32 emif_ddr_ext_phy_ctrl_20;
-       u32 emif_ddr_ext_phy_ctrl_20_shdw;
-       u32 emif_ddr_ext_phy_ctrl_21;
-       u32 emif_ddr_ext_phy_ctrl_21_shdw;
-       u32 emif_ddr_ext_phy_ctrl_22;
-       u32 emif_ddr_ext_phy_ctrl_22_shdw;
-       u32 emif_ddr_ext_phy_ctrl_23;
-       u32 emif_ddr_ext_phy_ctrl_23_shdw;
-       u32 emif_ddr_ext_phy_ctrl_24;
-       u32 emif_ddr_ext_phy_ctrl_24_shdw;
-       u32 emif_ddr_ext_phy_ctrl_25;
-       u32 emif_ddr_ext_phy_ctrl_25_shdw;
-       u32 emif_ddr_ext_phy_ctrl_26;
-       u32 emif_ddr_ext_phy_ctrl_26_shdw;
-       u32 emif_ddr_ext_phy_ctrl_27;
-       u32 emif_ddr_ext_phy_ctrl_27_shdw;
-       u32 emif_ddr_ext_phy_ctrl_28;
-       u32 emif_ddr_ext_phy_ctrl_28_shdw;
-       u32 emif_ddr_ext_phy_ctrl_29;
-       u32 emif_ddr_ext_phy_ctrl_29_shdw;
-       u32 emif_ddr_ext_phy_ctrl_30;
-       u32 emif_ddr_ext_phy_ctrl_30_shdw;
-       u32 emif_ddr_ext_phy_ctrl_31;
-       u32 emif_ddr_ext_phy_ctrl_31_shdw;
-       u32 emif_ddr_ext_phy_ctrl_32;
-       u32 emif_ddr_ext_phy_ctrl_32_shdw;
-       u32 emif_ddr_ext_phy_ctrl_33;
-       u32 emif_ddr_ext_phy_ctrl_33_shdw;
-       u32 emif_ddr_ext_phy_ctrl_34;
-       u32 emif_ddr_ext_phy_ctrl_34_shdw;
-       u32 emif_ddr_ext_phy_ctrl_35;
-       u32 emif_ddr_ext_phy_ctrl_35_shdw;
+       u32 emif_mod_id_rev;                    /* 0x000 */
+       u32 emif_status;                        /* 0x004 */
+       u32 emif_sdram_config;                  /* 0x008 */
+       u32 emif_lpddr2_nvm_config;             /* 0x00c */
+       u32 emif_sdram_ref_ctrl;                /* 0x010 */
+       u32 emif_sdram_ref_ctrl_shdw;           /* 0x014 */
+       u32 emif_sdram_tim_1;                   /* 0x018 */
+       u32 emif_sdram_tim_1_shdw;              /* 0x01c */
+       u32 emif_sdram_tim_2;                   /* 0x020 */
+       u32 emif_sdram_tim_2_shdw;              /* 0x024 */
+       u32 emif_sdram_tim_3;                   /* 0x028 */
+       u32 emif_sdram_tim_3_shdw;              /* 0x02c */
+       u32 emif_lpddr2_nvm_tim;                /* 0x030 */
+       u32 emif_lpddr2_nvm_tim_shdw;           /* 0x034 */
+       u32 emif_pwr_mgmt_ctrl;                 /* 0x038 */
+       u32 emif_pwr_mgmt_ctrl_shdw;            /* 0x03c */
+       u32 emif_lpddr2_mode_reg_data;          /* 0x040 */
+       u32 padding1[1];                        /* 0x044 */
+       u32 emif_lpddr2_mode_reg_data_es2;      /* 0x048 */
+       u32 padding11[1];                       /* 0x04c */
+       u32 emif_lpddr2_mode_reg_cfg;           /* 0x050 */
+       u32 emif_l3_config;                     /* 0x054 */
+       u32 emif_l3_cfg_val_1;                  /* 0x058 */
+       u32 emif_l3_cfg_val_2;                  /* 0x05c */
+       u32 emif_iodft_tlgc;                    /* 0x060 */
+       u32 padding2[7];                        /* 0x064 */
+       u32 emif_perf_cnt_1;                    /* 0x080 */
+       u32 emif_perf_cnt_2;                    /* 0x084 */
+       u32 emif_perf_cnt_cfg;                  /* 0x088 */
+       u32 emif_perf_cnt_sel;                  /* 0x08c */
+       u32 emif_perf_cnt_tim;                  /* 0x090 */
+       u32 padding3;                           /* 0x094 */
+       u32 emif_read_idlectrl;                 /* 0x098 */
+       u32 emif_read_idlectrl_shdw;            /* 0x09c */
+       u32 padding4;                           /* 0x0a0 */
+       u32 emif_irqstatus_raw_sys;             /* 0x0a4 */
+       u32 emif_irqstatus_raw_ll;              /* 0x0a8 */
+       u32 emif_irqstatus_sys;                 /* 0x0ac */
+       u32 emif_irqstatus_ll;                  /* 0x0b0 */
+       u32 emif_irqenable_set_sys;             /* 0x0b4 */
+       u32 emif_irqenable_set_ll;              /* 0x0b8 */
+       u32 emif_irqenable_clr_sys;             /* 0x0bc */
+       u32 emif_irqenable_clr_ll;              /* 0x0c0 */
+       u32 padding5;                           /* 0x0c4 */
+       u32 emif_zq_config;                     /* 0x0c8 */
+       u32 emif_temp_alert_config;             /* 0x0cc */
+       u32 emif_l3_err_log;                    /* 0x0d0 */
+       u32 emif_rd_wr_lvl_rmp_win;             /* 0x0d4 */
+       u32 emif_rd_wr_lvl_rmp_ctl;             /* 0x0d8 */
+       u32 emif_rd_wr_lvl_ctl;                 /* 0x0dc */
+       u32 padding6[1];                        /* 0x0e0 */
+       u32 emif_ddr_phy_ctrl_1;                /* 0x0e4 */
+       u32 emif_ddr_phy_ctrl_1_shdw;           /* 0x0e8 */
+       u32 emif_ddr_phy_ctrl_2;                /* 0x0ec */
+       u32 padding7[4];                        /* 0x0f0 */
+       u32 emif_prio_class_serv_map;           /* 0x100 */
+       u32 emif_connect_id_serv_1_map;         /* 0x104 */
+       u32 emif_connect_id_serv_2_map;         /* 0x108 */
+       u32 padding8[5];                        /* 0x10c */
+       u32 emif_rd_wr_exec_thresh;             /* 0x120 */
+       u32 emif_cos_config;                    /* 0x124 */
+       u32 padding9[6];                        /* 0x128 */
+       u32 emif_ddr_phy_status[28];            /* 0x140 */
+       u32 padding10[20];                      /* 0x1b0 */
+       u32 emif_ddr_ext_phy_ctrl_1;            /* 0x200 */
+       u32 emif_ddr_ext_phy_ctrl_1_shdw;       /* 0x204 */
+       u32 emif_ddr_ext_phy_ctrl_2;            /* 0x248 */
+       u32 emif_ddr_ext_phy_ctrl_2_shdw;       /* 0x24c */
+       u32 emif_ddr_ext_phy_ctrl_3;            /* 0x200 */
+       u32 emif_ddr_ext_phy_ctrl_3_shdw;       /* 0x204 */
+       u32 emif_ddr_ext_phy_ctrl_4;            /* 0x208 */
+       u32 emif_ddr_ext_phy_ctrl_4_shdw;       /* 0x20c */
+       u32 emif_ddr_ext_phy_ctrl_5;            /* 0x210 */
+       u32 emif_ddr_ext_phy_ctrl_5_shdw;       /* 0x214 */
+       u32 emif_ddr_ext_phy_ctrl_6;            /* 0x218 */
+       u32 emif_ddr_ext_phy_ctrl_6_shdw;       /* 0x21c */
+       u32 emif_ddr_ext_phy_ctrl_7;            /* 0x220 */
+       u32 emif_ddr_ext_phy_ctrl_7_shdw;       /* 0x224 */
+       u32 emif_ddr_ext_phy_ctrl_8;            /* 0x228 */
+       u32 emif_ddr_ext_phy_ctrl_8_shdw;       /* 0x22c */
+       u32 emif_ddr_ext_phy_ctrl_9;            /* 0x230 */
+       u32 emif_ddr_ext_phy_ctrl_9_shdw;       /* 0x234 */
+       u32 emif_ddr_ext_phy_ctrl_10;           /* 0x238 */
+       u32 emif_ddr_ext_phy_ctrl_10_shdw;      /* 0x23c */
+       u32 emif_ddr_ext_phy_ctrl_11;           /* 0x240 */
+       u32 emif_ddr_ext_phy_ctrl_11_shdw;      /* 0x244 */
+       u32 emif_ddr_ext_phy_ctrl_12;           /* 0x248 */
+       u32 emif_ddr_ext_phy_ctrl_12_shdw;      /* 0x24c */
+       u32 emif_ddr_ext_phy_ctrl_13;           /* 0x250 */
+       u32 emif_ddr_ext_phy_ctrl_13_shdw;      /* 0x254 */
+       u32 emif_ddr_ext_phy_ctrl_14;           /* 0x258 */
+       u32 emif_ddr_ext_phy_ctrl_14_shdw;      /* 0x25c */
+       u32 emif_ddr_ext_phy_ctrl_15;           /* 0x260 */
+       u32 emif_ddr_ext_phy_ctrl_15_shdw;      /* 0x264 */
+       u32 emif_ddr_ext_phy_ctrl_16;           /* 0x268 */
+       u32 emif_ddr_ext_phy_ctrl_16_shdw;      /* 0x26c */
+       u32 emif_ddr_ext_phy_ctrl_17;           /* 0x270 */
+       u32 emif_ddr_ext_phy_ctrl_17_shdw;      /* 0x274 */
+       u32 emif_ddr_ext_phy_ctrl_18;           /* 0x278 */
+       u32 emif_ddr_ext_phy_ctrl_18_shdw;      /* 0x27c */
+       u32 emif_ddr_ext_phy_ctrl_19;           /* 0x280 */
+       u32 emif_ddr_ext_phy_ctrl_19_shdw;      /* 0x284 */
+       u32 emif_ddr_ext_phy_ctrl_20;           /* 0x288 */
+       u32 emif_ddr_ext_phy_ctrl_20_shdw;      /* 0x28c */
+       u32 emif_ddr_ext_phy_ctrl_21;           /* 0x290 */
+       u32 emif_ddr_ext_phy_ctrl_21_shdw;      /* 0x294 */
+       u32 emif_ddr_ext_phy_ctrl_22;           /* 0x298 */
+       u32 emif_ddr_ext_phy_ctrl_22_shdw;      /* 0x29c */
+       u32 emif_ddr_ext_phy_ctrl_23;           /* 0x2a0 */
+       u32 emif_ddr_ext_phy_ctrl_23_shdw;      /* 0x2a4 */
+       u32 emif_ddr_ext_phy_ctrl_24;           /* 0x2a8 */
+       u32 emif_ddr_ext_phy_ctrl_24_shdw;      /* 0x2ac */
+       u32 emif_ddr_ext_phy_ctrl_25;           /* 0x2b0 */
+       u32 emif_ddr_ext_phy_ctrl_25_shdw;      /* 0x2b4 */
+       u32 emif_ddr_ext_phy_ctrl_26;           /* 0x2b8 */
+       u32 emif_ddr_ext_phy_ctrl_26_shdw;      /* 0x2bc */
+       u32 emif_ddr_ext_phy_ctrl_27;           /* 0x2c0 */
+       u32 emif_ddr_ext_phy_ctrl_27_shdw;      /* 0x2c4 */
+       u32 emif_ddr_ext_phy_ctrl_28;           /* 0x2c8 */
+       u32 emif_ddr_ext_phy_ctrl_28_shdw;      /* 0x2cc */
+       u32 emif_ddr_ext_phy_ctrl_29;           /* 0x2d0 */
+       u32 emif_ddr_ext_phy_ctrl_29_shdw;      /* 0x2d4 */
+       u32 emif_ddr_ext_phy_ctrl_30;           /* 0x2d8 */
+       u32 emif_ddr_ext_phy_ctrl_30_shdw;      /* 0x2dc */
+       u32 emif_ddr_ext_phy_ctrl_31;           /* 0x2e0 */
+       u32 emif_ddr_ext_phy_ctrl_31_shdw;      /* 0x2e4 */
+       u32 emif_ddr_ext_phy_ctrl_32;           /* 0x2e8 */
+       u32 emif_ddr_ext_phy_ctrl_32_shdw;      /* 0x2ec */
+       u32 emif_ddr_ext_phy_ctrl_33;           /* 0x2f0 */
+       u32 emif_ddr_ext_phy_ctrl_33_shdw;      /* 0x2f4 */
+       u32 emif_ddr_ext_phy_ctrl_34;           /* 0x2f8 */
+       u32 emif_ddr_ext_phy_ctrl_34_shdw;      /* 0x2fc */
+       u32 emif_ddr_ext_phy_ctrl_35;           /* 0x300 */
+       u32 emif_ddr_ext_phy_ctrl_35_shdw;      /* 0x304 */
        union {
-               u32 emif_ddr_ext_phy_ctrl_36;
+               u32 emif_ddr_ext_phy_ctrl_36;   /* 0x308 */
                u32 emif_ddr_fifo_misaligned_clear_1;
        };
        union {
-               u32 emif_ddr_ext_phy_ctrl_36_shdw;
+               u32 emif_ddr_ext_phy_ctrl_36_shdw; /* 0x30c */
                u32 emif_ddr_fifo_misaligned_clear_2;
        };
 };
@@ -1209,9 +1209,9 @@ static inline u32 emif_sdram_type(void)
 
 /* assert macros */
 #if defined(DEBUG)
-#define emif_assert(c) ({ if (!(c)) for (;;); })
+#define emif_assert(c) ({ if (!(c)) hang(); })
 #else
-#define emif_assert(c) ({ if (0) hang(); })
+#define emif_assert(c) (c)
 #endif
 
 #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
index 438f128326a67a6c5237df32a0f392efdabee1c7..5fb6506f4ead0b1ac44bb0ec18620419e1813b55 100644 (file)
@@ -25,6 +25,10 @@ struct arch_global_data {
        uint mp_alloc_top;
 #endif /* CONFIG_U_QE */
 
+#ifdef CONFIG_VIDEO_IPUV3
+       unsigned int    ipu_hw_rev;
+#endif
+
 #ifdef CONFIG_AT91FAMILY
        /* "static data" needed by at91's clock.c */
        unsigned long   cpu_clk_rate_hz;
index d5c1f7f255a3c5f6eee70634d6dd747ac5639530..8f9a11a288264e27d35244367f49991f06ff8bee 100644 (file)
@@ -150,11 +150,14 @@ struct mxs_dma_chan {
        unsigned int pending_num;
        struct list_head active;
        struct list_head done;
+       unsigned long timeout;
 };
 
 struct mxs_dma_desc *mxs_dma_desc_alloc(void);
 void mxs_dma_desc_free(struct mxs_dma_desc *);
 int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc);
+int mxs_dma_set_timeout(int channel, unsigned long timeout);
+unsigned long mxs_dma_get_timeout(int channel);
 
 int mxs_dma_go(int chan);
 void mxs_dma_init(void);
index e0a49be4ff79de66abdb22e420a94b354a83e89f..9ba5f6be9622ffe68d0d1c5b7add81e66ca752d6 100644 (file)
@@ -8,8 +8,8 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#ifndef __MACH_IOMUX_V3_H__
-#define __MACH_IOMUX_V3_H__
+#ifndef __ASM_ARCH_IOMUX_V3_H__
+#define __ASM_ARCH_IOMUX_V3_H__
 
 #include <common.h>
 
  *
  * IOMUX/PAD Bit field definitions
  *
- * MUX_CTRL_OFS:           0..11 (12)
- * PAD_CTRL_OFS:          12..23 (12)
- * SEL_INPUT_OFS:         24..35 (12)
- * MUX_MODE + SION:       36..40  (5)
- * PAD_CTRL + NO_PAD_CTRL: 41..58 (18)
- * SEL_INP:               59..62  (4)
- * reserved:                63    (1)
+ * MUX_CTRL_OFS:                0..11 (12)
+ * PAD_CTRL_OFS:               12..23 (12)
+ * SEL_INPUT_OFS:              24..35 (12)
+ * MUX_MODE + SION:            36..40  (5)
+ * PAD_CTRL + PAD_CTRL_VALID:  41..58 (18)
+ * SEL_INP:                    59..62  (4)
+ * reserved:                     63    (1)
 */
 
 typedef u64 iomux_v3_cfg_t;
@@ -59,13 +59,15 @@ typedef u64 iomux_v3_cfg_t;
 #define MUX_MODE_SHIFT         36
 #define MUX_MODE_MASK          ((iomux_v3_cfg_t)0x1f << MUX_MODE_SHIFT)
 #define MUX_PAD_CTRL_SHIFT     41
-#define MUX_PAD_CTRL_MASK      ((iomux_v3_cfg_t)0x3ffff << MUX_PAD_CTRL_SHIFT)
+#define MUX_PAD_CTRL_MASK      ((iomux_v3_cfg_t)0x1ffff << MUX_PAD_CTRL_SHIFT)
 #define MUX_SEL_INPUT_SHIFT    59
 #define MUX_SEL_INPUT_MASK     ((iomux_v3_cfg_t)0xf << MUX_SEL_INPUT_SHIFT)
 
 #define MUX_MODE_SION          ((iomux_v3_cfg_t)IOMUX_CONFIG_SION << \
        MUX_MODE_SHIFT)
-#define MUX_PAD_CTRL(x)                ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_SHIFT)
+#define __MUX_PAD_CTRL(x)      ((x) | __PAD_CTRL_VALID)
+#define MUX_PAD_CTRL(x)                (((iomux_v3_cfg_t)__MUX_PAD_CTRL(x) << \
+                                               MUX_PAD_CTRL_SHIFT))
 
 #define IOMUX_PAD(pad_ctrl_ofs, mux_ctrl_ofs, mux_mode, sel_input_ofs, \
                sel_input, pad_ctrl)                                    \
@@ -83,89 +85,94 @@ typedef u64 iomux_v3_cfg_t;
 #define NO_MUX_I               0
 #define NO_PAD_I               0
 
-#define NO_PAD_CTRL            (1 << 17)
+#define NO_MUX_I               0
+#define NO_PAD_I               0
+
+#define NO_PAD_CTRL            0
+#define __PAD_CTRL_VALID       (1 << 17)
+#define PAD_CTRL_VALID         ((iomux_v3_cfg_t)__PAD_CTRL_VALID << MUX_PAD_CTRL_SHIFT)
 
 #ifdef CONFIG_MX6
 
-#define PAD_CTL_HYS            (1 << 16)
+#define PAD_CTL_HYS            __MUX_PAD_CTRL(1 << 16)
 
-#define PAD_CTL_PUS_100K_DOWN  (0 << 14 | PAD_CTL_PUE)
-#define PAD_CTL_PUS_47K_UP     (1 << 14 | PAD_CTL_PUE)
-#define PAD_CTL_PUS_100K_UP    (2 << 14 | PAD_CTL_PUE)
-#define PAD_CTL_PUS_22K_UP     (3 << 14 | PAD_CTL_PUE)
-#define PAD_CTL_PUE            (1 << 13 | PAD_CTL_PKE)
-#define PAD_CTL_PKE            (1 << 12)
+#define PAD_CTL_PUS_100K_DOWN  __MUX_PAD_CTRL(0 << 14 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_47K_UP     __MUX_PAD_CTRL(1 << 14 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_100K_UP    __MUX_PAD_CTRL(2 << 14 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_22K_UP     __MUX_PAD_CTRL(3 << 14 | PAD_CTL_PUE)
+#define PAD_CTL_PUE            __MUX_PAD_CTRL(1 << 13 | PAD_CTL_PKE)
+#define PAD_CTL_PKE            __MUX_PAD_CTRL(1 << 12)
 
-#define PAD_CTL_ODE            (1 << 11)
+#define PAD_CTL_ODE            __MUX_PAD_CTRL(1 << 11)
 
-#define PAD_CTL_SPEED_LOW      (1 << 6)
-#define PAD_CTL_SPEED_MED      (2 << 6)
-#define PAD_CTL_SPEED_HIGH     (3 << 6)
+#define PAD_CTL_SPEED_LOW      __MUX_PAD_CTRL(1 << 6)
+#define PAD_CTL_SPEED_MED      __MUX_PAD_CTRL(2 << 6)
+#define PAD_CTL_SPEED_HIGH     __MUX_PAD_CTRL(3 << 6)
 
-#define PAD_CTL_DSE_DISABLE    (0 << 3)
-#define PAD_CTL_DSE_240ohm     (1 << 3)
-#define PAD_CTL_DSE_120ohm     (2 << 3)
-#define PAD_CTL_DSE_80ohm      (3 << 3)
-#define PAD_CTL_DSE_60ohm      (4 << 3)
-#define PAD_CTL_DSE_48ohm      (5 << 3)
-#define PAD_CTL_DSE_40ohm      (6 << 3)
-#define PAD_CTL_DSE_34ohm      (7 << 3)
+#define PAD_CTL_DSE_DISABLE    __MUX_PAD_CTRL(0 << 3)
+#define PAD_CTL_DSE_240ohm     __MUX_PAD_CTRL(1 << 3)
+#define PAD_CTL_DSE_120ohm     __MUX_PAD_CTRL(2 << 3)
+#define PAD_CTL_DSE_80ohm      __MUX_PAD_CTRL(3 << 3)
+#define PAD_CTL_DSE_60ohm      __MUX_PAD_CTRL(4 << 3)
+#define PAD_CTL_DSE_48ohm      __MUX_PAD_CTRL(5 << 3)
+#define PAD_CTL_DSE_40ohm      __MUX_PAD_CTRL(6 << 3)
+#define PAD_CTL_DSE_34ohm      __MUX_PAD_CTRL(7 << 3)
 
 #if defined CONFIG_MX6SL
-#define PAD_CTL_LVE            (1 << 1)
-#define PAD_CTL_LVE_BIT                (1 << 22)
+#define PAD_CTL_LVE            __MUX_PAD_CTRL(1 << 1)
+#define PAD_CTL_LVE_BIT                __MUX_PAD_CTRL(1 << 22)
 #endif
 
 #elif defined(CONFIG_VF610)
 
 #define PAD_MUX_MODE_SHIFT     20
 
-#define PAD_CTL_INPUT_DIFFERENTIAL (1 << 16)
+#define PAD_CTL_INPUT_DIFFERENTIAL __MUX_PAD_CTRL(1 << 16)
 
-#define PAD_CTL_SPEED_MED      (1 << 12)
-#define PAD_CTL_SPEED_HIGH     (3 << 12)
+#define PAD_CTL_SPEED_MED      __MUX_PAD_CTRL(1 << 12)
+#define PAD_CTL_SPEED_HIGH     __MUX_PAD_CTRL(3 << 12)
 
-#define PAD_CTL_SRE            (1 << 11)
+#define PAD_CTL_SRE            __MUX_PAD_CTRL(1 << 11)
 
-#define PAD_CTL_DSE_150ohm     (1 << 6)
-#define PAD_CTL_DSE_50ohm      (3 << 6)
-#define PAD_CTL_DSE_25ohm      (6 << 6)
-#define PAD_CTL_DSE_20ohm      (7 << 6)
+#define PAD_CTL_DSE_150ohm     __MUX_PAD_CTRL(1 << 6)
+#define PAD_CTL_DSE_50ohm      __MUX_PAD_CTRL(3 << 6)
+#define PAD_CTL_DSE_25ohm      __MUX_PAD_CTRL(6 << 6)
+#define PAD_CTL_DSE_20ohm      __MUX_PAD_CTRL(7 << 6)
 
-#define PAD_CTL_PUS_47K_UP     (1 << 4 | PAD_CTL_PUE)
-#define PAD_CTL_PUS_100K_UP    (2 << 4 | PAD_CTL_PUE)
-#define PAD_CTL_PUS_22K_UP     (3 << 4 | PAD_CTL_PUE)
-#define PAD_CTL_PKE            (1 << 3)
-#define PAD_CTL_PUE            (1 << 2 | PAD_CTL_PKE)
+#define PAD_CTL_PUS_47K_UP     __MUX_PAD_CTRL(1 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_100K_UP    __MUX_PAD_CTRL(2 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_22K_UP     __MUX_PAD_CTRL(3 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PKE            __MUX_PAD_CTRL(1 << 3)
+#define PAD_CTL_PUE            __MUX_PAD_CTRL(1 << 2 | PAD_CTL_PKE)
 
-#define PAD_CTL_OBE_IBE_ENABLE (3 << 0)
-#define PAD_CTL_OBE_ENABLE     (1 << 1)
-#define PAD_CTL_IBE_ENABLE     (1 << 0)
+#define PAD_CTL_OBE_IBE_ENABLE __MUX_PAD_CTRL(3 << 0)
+#define PAD_CTL_OBE_ENABLE     __MUX_PAD_CTRL(1 << 1)
+#define PAD_CTL_IBE_ENABLE     __MUX_PAD_CTRL(1 << 0)
 
 #else
 
-#define PAD_CTL_DVS            (1 << 13)
-#define PAD_CTL_INPUT_DDR      (1 << 9)
-#define PAD_CTL_HYS            (1 << 8)
+#define PAD_CTL_DVS            __MUX_PAD_CTRL(1 << 13)
+#define PAD_CTL_INPUT_DDR      __MUX_PAD_CTRL(1 << 9)
+#define PAD_CTL_HYS            __MUX_PAD_CTRL(1 << 8)
 
-#define PAD_CTL_PKE            (1 << 7)
-#define PAD_CTL_PUE            (1 << 6 | PAD_CTL_PKE)
-#define PAD_CTL_PUS_100K_DOWN  (0 << 4 | PAD_CTL_PUE)
-#define PAD_CTL_PUS_47K_UP     (1 << 4 | PAD_CTL_PUE)
-#define PAD_CTL_PUS_100K_UP    (2 << 4 | PAD_CTL_PUE)
-#define PAD_CTL_PUS_22K_UP     (3 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PKE            __MUX_PAD_CTRL(1 << 7)
+#define PAD_CTL_PUE            __MUX_PAD_CTRL(1 << 6 | PAD_CTL_PKE)
+#define PAD_CTL_PUS_100K_DOWN  __MUX_PAD_CTRL(0 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_47K_UP     __MUX_PAD_CTRL(1 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_100K_UP    __MUX_PAD_CTRL(2 << 4 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_22K_UP     __MUX_PAD_CTRL(3 << 4 | PAD_CTL_PUE)
 
-#define PAD_CTL_ODE            (1 << 3)
+#define PAD_CTL_ODE            __MUX_PAD_CTRL(1 << 3)
 
-#define PAD_CTL_DSE_LOW                (0 << 1)
-#define PAD_CTL_DSE_MED                (1 << 1)
-#define PAD_CTL_DSE_HIGH       (2 << 1)
-#define PAD_CTL_DSE_MAX                (3 << 1)
+#define PAD_CTL_DSE_LOW                __MUX_PAD_CTRL(0 << 1)
+#define PAD_CTL_DSE_MED                __MUX_PAD_CTRL(1 << 1)
+#define PAD_CTL_DSE_HIGH       __MUX_PAD_CTRL(2 << 1)
+#define PAD_CTL_DSE_MAX                __MUX_PAD_CTRL(3 << 1)
 
 #endif
 
-#define PAD_CTL_SRE_SLOW       (0 << 0)
-#define PAD_CTL_SRE_FAST       (1 << 0)
+#define PAD_CTL_SRE_SLOW       __MUX_PAD_CTRL(0 << 0)
+#define PAD_CTL_SRE_FAST       __MUX_PAD_CTRL(1 << 0)
 
 #define IOMUX_CONFIG_SION      0x10
 
@@ -179,7 +186,7 @@ typedef u64 iomux_v3_cfg_t;
 #define GPIO_PORTE             (4 << GPIO_PORT_SHIFT)
 #define GPIO_PORTF             (5 << GPIO_PORT_SHIFT)
 
-void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
+void imx_iomux_v3_setup_pad(const iomux_v3_cfg_t const pad);
 void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
                                     unsigned count);
 /*
@@ -213,4 +220,4 @@ if (is_cpu_type(MXC_CPU_MX6Q)) {                            \
        imx_iomux_v3_setup_multiple_pads(x, ARRAY_SIZE(x))
 #endif
 
-#endif /* __MACH_IOMUX_V3_H__*/
+#endif /* __ASM_ARCH_IOMUX_V3_H__*/
index ca7743600420048b5f404130dd35fcafe52f1fbe..bcbde05df39c68981abb75003b314e6e4af19eb5 100644 (file)
 
 #if defined(CONFIG_MX23)
 struct mxs_apbh_regs {
-       mxs_reg_32(hw_apbh_ctrl0)
-       mxs_reg_32(hw_apbh_ctrl1)
-       mxs_reg_32(hw_apbh_ctrl2)
-       mxs_reg_32(hw_apbh_channel_ctrl)
+       mxs_reg_32(hw_apbh_ctrl0);
+       mxs_reg_32(hw_apbh_ctrl1);
+       mxs_reg_32(hw_apbh_ctrl2);
+       mxs_reg_32(hw_apbh_channel_ctrl);
 
        union {
        struct {
-               mxs_reg_32(hw_apbh_ch_curcmdar)
-               mxs_reg_32(hw_apbh_ch_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch_cmd)
-               mxs_reg_32(hw_apbh_ch_bar)
-               mxs_reg_32(hw_apbh_ch_sema)
-               mxs_reg_32(hw_apbh_ch_debug1)
-               mxs_reg_32(hw_apbh_ch_debug2)
+               mxs_reg_32(hw_apbh_ch_curcmdar);
+               mxs_reg_32(hw_apbh_ch_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch_cmd);
+               mxs_reg_32(hw_apbh_ch_bar);
+               mxs_reg_32(hw_apbh_ch_sema);
+               mxs_reg_32(hw_apbh_ch_debug1);
+               mxs_reg_32(hw_apbh_ch_debug2);
        } ch[8];
        struct {
-               mxs_reg_32(hw_apbh_ch0_curcmdar)
-               mxs_reg_32(hw_apbh_ch0_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch0_cmd)
-               mxs_reg_32(hw_apbh_ch0_bar)
-               mxs_reg_32(hw_apbh_ch0_sema)
-               mxs_reg_32(hw_apbh_ch0_debug1)
-               mxs_reg_32(hw_apbh_ch0_debug2)
-               mxs_reg_32(hw_apbh_ch1_curcmdar)
-               mxs_reg_32(hw_apbh_ch1_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch1_cmd)
-               mxs_reg_32(hw_apbh_ch1_bar)
-               mxs_reg_32(hw_apbh_ch1_sema)
-               mxs_reg_32(hw_apbh_ch1_debug1)
-               mxs_reg_32(hw_apbh_ch1_debug2)
-               mxs_reg_32(hw_apbh_ch2_curcmdar)
-               mxs_reg_32(hw_apbh_ch2_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch2_cmd)
-               mxs_reg_32(hw_apbh_ch2_bar)
-               mxs_reg_32(hw_apbh_ch2_sema)
-               mxs_reg_32(hw_apbh_ch2_debug1)
-               mxs_reg_32(hw_apbh_ch2_debug2)
-               mxs_reg_32(hw_apbh_ch3_curcmdar)
-               mxs_reg_32(hw_apbh_ch3_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch3_cmd)
-               mxs_reg_32(hw_apbh_ch3_bar)
-               mxs_reg_32(hw_apbh_ch3_sema)
-               mxs_reg_32(hw_apbh_ch3_debug1)
-               mxs_reg_32(hw_apbh_ch3_debug2)
-               mxs_reg_32(hw_apbh_ch4_curcmdar)
-               mxs_reg_32(hw_apbh_ch4_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch4_cmd)
-               mxs_reg_32(hw_apbh_ch4_bar)
-               mxs_reg_32(hw_apbh_ch4_sema)
-               mxs_reg_32(hw_apbh_ch4_debug1)
-               mxs_reg_32(hw_apbh_ch4_debug2)
-               mxs_reg_32(hw_apbh_ch5_curcmdar)
-               mxs_reg_32(hw_apbh_ch5_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch5_cmd)
-               mxs_reg_32(hw_apbh_ch5_bar)
-               mxs_reg_32(hw_apbh_ch5_sema)
-               mxs_reg_32(hw_apbh_ch5_debug1)
-               mxs_reg_32(hw_apbh_ch5_debug2)
-               mxs_reg_32(hw_apbh_ch6_curcmdar)
-               mxs_reg_32(hw_apbh_ch6_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch6_cmd)
-               mxs_reg_32(hw_apbh_ch6_bar)
-               mxs_reg_32(hw_apbh_ch6_sema)
-               mxs_reg_32(hw_apbh_ch6_debug1)
-               mxs_reg_32(hw_apbh_ch6_debug2)
-               mxs_reg_32(hw_apbh_ch7_curcmdar)
-               mxs_reg_32(hw_apbh_ch7_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch7_cmd)
-               mxs_reg_32(hw_apbh_ch7_bar)
-               mxs_reg_32(hw_apbh_ch7_sema)
-               mxs_reg_32(hw_apbh_ch7_debug1)
-               mxs_reg_32(hw_apbh_ch7_debug2)
+               mxs_reg_32(hw_apbh_ch0_curcmdar);
+               mxs_reg_32(hw_apbh_ch0_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch0_cmd);
+               mxs_reg_32(hw_apbh_ch0_bar);
+               mxs_reg_32(hw_apbh_ch0_sema);
+               mxs_reg_32(hw_apbh_ch0_debug1);
+               mxs_reg_32(hw_apbh_ch0_debug2);
+               mxs_reg_32(hw_apbh_ch1_curcmdar);
+               mxs_reg_32(hw_apbh_ch1_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch1_cmd);
+               mxs_reg_32(hw_apbh_ch1_bar);
+               mxs_reg_32(hw_apbh_ch1_sema);
+               mxs_reg_32(hw_apbh_ch1_debug1);
+               mxs_reg_32(hw_apbh_ch1_debug2);
+               mxs_reg_32(hw_apbh_ch2_curcmdar);
+               mxs_reg_32(hw_apbh_ch2_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch2_cmd);
+               mxs_reg_32(hw_apbh_ch2_bar);
+               mxs_reg_32(hw_apbh_ch2_sema);
+               mxs_reg_32(hw_apbh_ch2_debug1);
+               mxs_reg_32(hw_apbh_ch2_debug2);
+               mxs_reg_32(hw_apbh_ch3_curcmdar);
+               mxs_reg_32(hw_apbh_ch3_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch3_cmd);
+               mxs_reg_32(hw_apbh_ch3_bar);
+               mxs_reg_32(hw_apbh_ch3_sema);
+               mxs_reg_32(hw_apbh_ch3_debug1);
+               mxs_reg_32(hw_apbh_ch3_debug2);
+               mxs_reg_32(hw_apbh_ch4_curcmdar);
+               mxs_reg_32(hw_apbh_ch4_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch4_cmd);
+               mxs_reg_32(hw_apbh_ch4_bar);
+               mxs_reg_32(hw_apbh_ch4_sema);
+               mxs_reg_32(hw_apbh_ch4_debug1);
+               mxs_reg_32(hw_apbh_ch4_debug2);
+               mxs_reg_32(hw_apbh_ch5_curcmdar);
+               mxs_reg_32(hw_apbh_ch5_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch5_cmd);
+               mxs_reg_32(hw_apbh_ch5_bar);
+               mxs_reg_32(hw_apbh_ch5_sema);
+               mxs_reg_32(hw_apbh_ch5_debug1);
+               mxs_reg_32(hw_apbh_ch5_debug2);
+               mxs_reg_32(hw_apbh_ch6_curcmdar);
+               mxs_reg_32(hw_apbh_ch6_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch6_cmd);
+               mxs_reg_32(hw_apbh_ch6_bar);
+               mxs_reg_32(hw_apbh_ch6_sema);
+               mxs_reg_32(hw_apbh_ch6_debug1);
+               mxs_reg_32(hw_apbh_ch6_debug2);
+               mxs_reg_32(hw_apbh_ch7_curcmdar);
+               mxs_reg_32(hw_apbh_ch7_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch7_cmd);
+               mxs_reg_32(hw_apbh_ch7_bar);
+               mxs_reg_32(hw_apbh_ch7_sema);
+               mxs_reg_32(hw_apbh_ch7_debug1);
+               mxs_reg_32(hw_apbh_ch7_debug2);
        };
        };
-       mxs_reg_32(hw_apbh_version)
+       mxs_reg_32(hw_apbh_version);
 };
 
 #elif (defined(CONFIG_MX28) || defined(CONFIG_MX6))
 struct mxs_apbh_regs {
-       mxs_reg_32(hw_apbh_ctrl0)
-       mxs_reg_32(hw_apbh_ctrl1)
-       mxs_reg_32(hw_apbh_ctrl2)
-       mxs_reg_32(hw_apbh_channel_ctrl)
-       mxs_reg_32(hw_apbh_devsel)
-       mxs_reg_32(hw_apbh_dma_burst_size)
-       mxs_reg_32(hw_apbh_debug)
+       mxs_reg_32(hw_apbh_ctrl0);                              /* 0x000 */
+       mxs_reg_32(hw_apbh_ctrl1);                              /* 0x010 */
+       mxs_reg_32(hw_apbh_ctrl2);                              /* 0x020 */
+       mxs_reg_32(hw_apbh_channel_ctrl);                       /* 0x030 */
+       mxs_reg_32(hw_apbh_devsel);                             /* 0x040 */
+       mxs_reg_32(hw_apbh_dma_burst_size);                     /* 0x050 */
+       mxs_reg_32(hw_apbh_debug);                              /* 0x060 */
 
-       uint32_t        reserved[36];
+       reg_32(reserved[9]);                                    /* 0x064-0x0fc */
 
        union {
        struct {
-               mxs_reg_32(hw_apbh_ch_curcmdar)
-               mxs_reg_32(hw_apbh_ch_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch_cmd)
-               mxs_reg_32(hw_apbh_ch_bar)
-               mxs_reg_32(hw_apbh_ch_sema)
-               mxs_reg_32(hw_apbh_ch_debug1)
-               mxs_reg_32(hw_apbh_ch_debug2)
+               mxs_reg_32(hw_apbh_ch_curcmdar);
+               mxs_reg_32(hw_apbh_ch_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch_cmd);
+               mxs_reg_32(hw_apbh_ch_bar);
+               mxs_reg_32(hw_apbh_ch_sema);
+               mxs_reg_32(hw_apbh_ch_debug1);
+               mxs_reg_32(hw_apbh_ch_debug2);
        } ch[16];
        struct {
-               mxs_reg_32(hw_apbh_ch0_curcmdar)
-               mxs_reg_32(hw_apbh_ch0_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch0_cmd)
-               mxs_reg_32(hw_apbh_ch0_bar)
-               mxs_reg_32(hw_apbh_ch0_sema)
-               mxs_reg_32(hw_apbh_ch0_debug1)
-               mxs_reg_32(hw_apbh_ch0_debug2)
-               mxs_reg_32(hw_apbh_ch1_curcmdar)
-               mxs_reg_32(hw_apbh_ch1_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch1_cmd)
-               mxs_reg_32(hw_apbh_ch1_bar)
-               mxs_reg_32(hw_apbh_ch1_sema)
-               mxs_reg_32(hw_apbh_ch1_debug1)
-               mxs_reg_32(hw_apbh_ch1_debug2)
-               mxs_reg_32(hw_apbh_ch2_curcmdar)
-               mxs_reg_32(hw_apbh_ch2_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch2_cmd)
-               mxs_reg_32(hw_apbh_ch2_bar)
-               mxs_reg_32(hw_apbh_ch2_sema)
-               mxs_reg_32(hw_apbh_ch2_debug1)
-               mxs_reg_32(hw_apbh_ch2_debug2)
-               mxs_reg_32(hw_apbh_ch3_curcmdar)
-               mxs_reg_32(hw_apbh_ch3_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch3_cmd)
-               mxs_reg_32(hw_apbh_ch3_bar)
-               mxs_reg_32(hw_apbh_ch3_sema)
-               mxs_reg_32(hw_apbh_ch3_debug1)
-               mxs_reg_32(hw_apbh_ch3_debug2)
-               mxs_reg_32(hw_apbh_ch4_curcmdar)
-               mxs_reg_32(hw_apbh_ch4_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch4_cmd)
-               mxs_reg_32(hw_apbh_ch4_bar)
-               mxs_reg_32(hw_apbh_ch4_sema)
-               mxs_reg_32(hw_apbh_ch4_debug1)
-               mxs_reg_32(hw_apbh_ch4_debug2)
-               mxs_reg_32(hw_apbh_ch5_curcmdar)
-               mxs_reg_32(hw_apbh_ch5_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch5_cmd)
-               mxs_reg_32(hw_apbh_ch5_bar)
-               mxs_reg_32(hw_apbh_ch5_sema)
-               mxs_reg_32(hw_apbh_ch5_debug1)
-               mxs_reg_32(hw_apbh_ch5_debug2)
-               mxs_reg_32(hw_apbh_ch6_curcmdar)
-               mxs_reg_32(hw_apbh_ch6_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch6_cmd)
-               mxs_reg_32(hw_apbh_ch6_bar)
-               mxs_reg_32(hw_apbh_ch6_sema)
-               mxs_reg_32(hw_apbh_ch6_debug1)
-               mxs_reg_32(hw_apbh_ch6_debug2)
-               mxs_reg_32(hw_apbh_ch7_curcmdar)
-               mxs_reg_32(hw_apbh_ch7_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch7_cmd)
-               mxs_reg_32(hw_apbh_ch7_bar)
-               mxs_reg_32(hw_apbh_ch7_sema)
-               mxs_reg_32(hw_apbh_ch7_debug1)
-               mxs_reg_32(hw_apbh_ch7_debug2)
-               mxs_reg_32(hw_apbh_ch8_curcmdar)
-               mxs_reg_32(hw_apbh_ch8_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch8_cmd)
-               mxs_reg_32(hw_apbh_ch8_bar)
-               mxs_reg_32(hw_apbh_ch8_sema)
-               mxs_reg_32(hw_apbh_ch8_debug1)
-               mxs_reg_32(hw_apbh_ch8_debug2)
-               mxs_reg_32(hw_apbh_ch9_curcmdar)
-               mxs_reg_32(hw_apbh_ch9_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch9_cmd)
-               mxs_reg_32(hw_apbh_ch9_bar)
-               mxs_reg_32(hw_apbh_ch9_sema)
-               mxs_reg_32(hw_apbh_ch9_debug1)
-               mxs_reg_32(hw_apbh_ch9_debug2)
-               mxs_reg_32(hw_apbh_ch10_curcmdar)
-               mxs_reg_32(hw_apbh_ch10_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch10_cmd)
-               mxs_reg_32(hw_apbh_ch10_bar)
-               mxs_reg_32(hw_apbh_ch10_sema)
-               mxs_reg_32(hw_apbh_ch10_debug1)
-               mxs_reg_32(hw_apbh_ch10_debug2)
-               mxs_reg_32(hw_apbh_ch11_curcmdar)
-               mxs_reg_32(hw_apbh_ch11_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch11_cmd)
-               mxs_reg_32(hw_apbh_ch11_bar)
-               mxs_reg_32(hw_apbh_ch11_sema)
-               mxs_reg_32(hw_apbh_ch11_debug1)
-               mxs_reg_32(hw_apbh_ch11_debug2)
-               mxs_reg_32(hw_apbh_ch12_curcmdar)
-               mxs_reg_32(hw_apbh_ch12_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch12_cmd)
-               mxs_reg_32(hw_apbh_ch12_bar)
-               mxs_reg_32(hw_apbh_ch12_sema)
-               mxs_reg_32(hw_apbh_ch12_debug1)
-               mxs_reg_32(hw_apbh_ch12_debug2)
-               mxs_reg_32(hw_apbh_ch13_curcmdar)
-               mxs_reg_32(hw_apbh_ch13_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch13_cmd)
-               mxs_reg_32(hw_apbh_ch13_bar)
-               mxs_reg_32(hw_apbh_ch13_sema)
-               mxs_reg_32(hw_apbh_ch13_debug1)
-               mxs_reg_32(hw_apbh_ch13_debug2)
-               mxs_reg_32(hw_apbh_ch14_curcmdar)
-               mxs_reg_32(hw_apbh_ch14_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch14_cmd)
-               mxs_reg_32(hw_apbh_ch14_bar)
-               mxs_reg_32(hw_apbh_ch14_sema)
-               mxs_reg_32(hw_apbh_ch14_debug1)
-               mxs_reg_32(hw_apbh_ch14_debug2)
-               mxs_reg_32(hw_apbh_ch15_curcmdar)
-               mxs_reg_32(hw_apbh_ch15_nxtcmdar)
-               mxs_reg_32(hw_apbh_ch15_cmd)
-               mxs_reg_32(hw_apbh_ch15_bar)
-               mxs_reg_32(hw_apbh_ch15_sema)
-               mxs_reg_32(hw_apbh_ch15_debug1)
-               mxs_reg_32(hw_apbh_ch15_debug2)
+               mxs_reg_32(hw_apbh_ch0_curcmdar);
+               mxs_reg_32(hw_apbh_ch0_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch0_cmd);
+               mxs_reg_32(hw_apbh_ch0_bar);
+               mxs_reg_32(hw_apbh_ch0_sema);
+               mxs_reg_32(hw_apbh_ch0_debug1);
+               mxs_reg_32(hw_apbh_ch0_debug2);
+               mxs_reg_32(hw_apbh_ch1_curcmdar);
+               mxs_reg_32(hw_apbh_ch1_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch1_cmd);
+               mxs_reg_32(hw_apbh_ch1_bar);
+               mxs_reg_32(hw_apbh_ch1_sema);
+               mxs_reg_32(hw_apbh_ch1_debug1);
+               mxs_reg_32(hw_apbh_ch1_debug2);
+               mxs_reg_32(hw_apbh_ch2_curcmdar);
+               mxs_reg_32(hw_apbh_ch2_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch2_cmd);
+               mxs_reg_32(hw_apbh_ch2_bar);
+               mxs_reg_32(hw_apbh_ch2_sema);
+               mxs_reg_32(hw_apbh_ch2_debug1);
+               mxs_reg_32(hw_apbh_ch2_debug2);
+               mxs_reg_32(hw_apbh_ch3_curcmdar);
+               mxs_reg_32(hw_apbh_ch3_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch3_cmd);
+               mxs_reg_32(hw_apbh_ch3_bar);
+               mxs_reg_32(hw_apbh_ch3_sema);
+               mxs_reg_32(hw_apbh_ch3_debug1);
+               mxs_reg_32(hw_apbh_ch3_debug2);
+               mxs_reg_32(hw_apbh_ch4_curcmdar);
+               mxs_reg_32(hw_apbh_ch4_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch4_cmd);
+               mxs_reg_32(hw_apbh_ch4_bar);
+               mxs_reg_32(hw_apbh_ch4_sema);
+               mxs_reg_32(hw_apbh_ch4_debug1);
+               mxs_reg_32(hw_apbh_ch4_debug2);
+               mxs_reg_32(hw_apbh_ch5_curcmdar);
+               mxs_reg_32(hw_apbh_ch5_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch5_cmd);
+               mxs_reg_32(hw_apbh_ch5_bar);
+               mxs_reg_32(hw_apbh_ch5_sema);
+               mxs_reg_32(hw_apbh_ch5_debug1);
+               mxs_reg_32(hw_apbh_ch5_debug2);
+               mxs_reg_32(hw_apbh_ch6_curcmdar);
+               mxs_reg_32(hw_apbh_ch6_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch6_cmd);
+               mxs_reg_32(hw_apbh_ch6_bar);
+               mxs_reg_32(hw_apbh_ch6_sema);
+               mxs_reg_32(hw_apbh_ch6_debug1);
+               mxs_reg_32(hw_apbh_ch6_debug2);
+               mxs_reg_32(hw_apbh_ch7_curcmdar);
+               mxs_reg_32(hw_apbh_ch7_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch7_cmd);
+               mxs_reg_32(hw_apbh_ch7_bar);
+               mxs_reg_32(hw_apbh_ch7_sema);
+               mxs_reg_32(hw_apbh_ch7_debug1);
+               mxs_reg_32(hw_apbh_ch7_debug2);
+               mxs_reg_32(hw_apbh_ch8_curcmdar);
+               mxs_reg_32(hw_apbh_ch8_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch8_cmd);
+               mxs_reg_32(hw_apbh_ch8_bar);
+               mxs_reg_32(hw_apbh_ch8_sema);
+               mxs_reg_32(hw_apbh_ch8_debug1);
+               mxs_reg_32(hw_apbh_ch8_debug2);
+               mxs_reg_32(hw_apbh_ch9_curcmdar);
+               mxs_reg_32(hw_apbh_ch9_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch9_cmd);
+               mxs_reg_32(hw_apbh_ch9_bar);
+               mxs_reg_32(hw_apbh_ch9_sema);
+               mxs_reg_32(hw_apbh_ch9_debug1);
+               mxs_reg_32(hw_apbh_ch9_debug2);
+               mxs_reg_32(hw_apbh_ch10_curcmdar);
+               mxs_reg_32(hw_apbh_ch10_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch10_cmd);
+               mxs_reg_32(hw_apbh_ch10_bar);
+               mxs_reg_32(hw_apbh_ch10_sema);
+               mxs_reg_32(hw_apbh_ch10_debug1);
+               mxs_reg_32(hw_apbh_ch10_debug2);
+               mxs_reg_32(hw_apbh_ch11_curcmdar);
+               mxs_reg_32(hw_apbh_ch11_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch11_cmd);
+               mxs_reg_32(hw_apbh_ch11_bar);
+               mxs_reg_32(hw_apbh_ch11_sema);
+               mxs_reg_32(hw_apbh_ch11_debug1);
+               mxs_reg_32(hw_apbh_ch11_debug2);
+               mxs_reg_32(hw_apbh_ch12_curcmdar);
+               mxs_reg_32(hw_apbh_ch12_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch12_cmd);
+               mxs_reg_32(hw_apbh_ch12_bar);
+               mxs_reg_32(hw_apbh_ch12_sema);
+               mxs_reg_32(hw_apbh_ch12_debug1);
+               mxs_reg_32(hw_apbh_ch12_debug2);
+               mxs_reg_32(hw_apbh_ch13_curcmdar);
+               mxs_reg_32(hw_apbh_ch13_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch13_cmd);
+               mxs_reg_32(hw_apbh_ch13_bar);
+               mxs_reg_32(hw_apbh_ch13_sema);
+               mxs_reg_32(hw_apbh_ch13_debug1);
+               mxs_reg_32(hw_apbh_ch13_debug2);
+               mxs_reg_32(hw_apbh_ch14_curcmdar);
+               mxs_reg_32(hw_apbh_ch14_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch14_cmd);
+               mxs_reg_32(hw_apbh_ch14_bar);
+               mxs_reg_32(hw_apbh_ch14_sema);
+               mxs_reg_32(hw_apbh_ch14_debug1);
+               mxs_reg_32(hw_apbh_ch14_debug2);
+               mxs_reg_32(hw_apbh_ch15_curcmdar);
+               mxs_reg_32(hw_apbh_ch15_nxtcmdar);
+               mxs_reg_32(hw_apbh_ch15_cmd);
+               mxs_reg_32(hw_apbh_ch15_bar);
+               mxs_reg_32(hw_apbh_ch15_sema);
+               mxs_reg_32(hw_apbh_ch15_debug1);
+               mxs_reg_32(hw_apbh_ch15_debug2);
        };
        };
-       mxs_reg_32(hw_apbh_version)
+       mxs_reg_32(hw_apbh_version);
 };
 #endif
 
index a33d3419b9f6461d87a428c30f818c5656685e0e..1ed5d94dd46e6294f03b8333722abfb78b173d43 100644 (file)
 #include <asm/imx-common/regs-common.h>
 
 #ifndef        __ASSEMBLY__
-struct mxs_bch_regs {
-       mxs_reg_32(hw_bch_ctrl)
-       mxs_reg_32(hw_bch_status0)
-       mxs_reg_32(hw_bch_mode)
-       mxs_reg_32(hw_bch_encodeptr)
-       mxs_reg_32(hw_bch_dataptr)
-       mxs_reg_32(hw_bch_metaptr)
+struct bch_regs {
+       mxs_reg_32(hw_bch_ctrl);
+       mxs_reg_32(hw_bch_status0);
+       mxs_reg_32(hw_bch_mode);
+       mxs_reg_32(hw_bch_encodeptr);
+       mxs_reg_32(hw_bch_dataptr);
+       mxs_reg_32(hw_bch_metaptr);
 
        uint32_t        reserved[4];
 
-       mxs_reg_32(hw_bch_layoutselect)
-       mxs_reg_32(hw_bch_flash0layout0)
-       mxs_reg_32(hw_bch_flash0layout1)
-       mxs_reg_32(hw_bch_flash1layout0)
-       mxs_reg_32(hw_bch_flash1layout1)
-       mxs_reg_32(hw_bch_flash2layout0)
-       mxs_reg_32(hw_bch_flash2layout1)
-       mxs_reg_32(hw_bch_flash3layout0)
-       mxs_reg_32(hw_bch_flash3layout1)
-       mxs_reg_32(hw_bch_dbgkesread)
-       mxs_reg_32(hw_bch_dbgcsferead)
-       mxs_reg_32(hw_bch_dbgsyndegread)
-       mxs_reg_32(hw_bch_dbgahbmread)
-       mxs_reg_32(hw_bch_blockname)
-       mxs_reg_32(hw_bch_version)
+       mxs_reg_32(hw_bch_layoutselect);
+       mxs_reg_32(hw_bch_flash0layout0);
+       mxs_reg_32(hw_bch_flash0layout1);
+       mxs_reg_32(hw_bch_flash1layout0);
+       mxs_reg_32(hw_bch_flash1layout1);
+       mxs_reg_32(hw_bch_flash2layout0);
+       mxs_reg_32(hw_bch_flash2layout1);
+       mxs_reg_32(hw_bch_flash3layout0);
+       mxs_reg_32(hw_bch_flash3layout1);
+       mxs_reg_32(hw_bch_dbgkesread);
+       mxs_reg_32(hw_bch_dbgcsferead);
+       mxs_reg_32(hw_bch_dbgsyndegread);
+       mxs_reg_32(hw_bch_dbgahbmread);
+       mxs_reg_32(hw_bch_blockname);
+       mxs_reg_32(hw_bch_version);
 };
 #endif
 
+#define BCH_BASE_ADDRESS                               MXS_BCH_BASE
+
 #define        BCH_CTRL_SFTRST                                 (1 << 31)
 #define        BCH_CTRL_CLKGATE                                (1 << 30)
 #define        BCH_CTRL_DEBUGSYNDROME                          (1 << 22)
index e54a220fa3e8c93e2e55c82c75172df1a06a5a2f..6fdcc5987f8ade451920789a245d7e673aa38c99 100644 (file)
  *
  */
 
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+
 #define        __mxs_reg_8(name)               \
        uint8_t name[4];                \
        uint8_t name##_set[4];          \
        uint8_t name##_clr[4];          \
-       uint8_t name##_tog[4];          \
+       uint8_t name##_tog[4]
 
 #define        __mxs_reg_32(name)              \
        uint32_t name;                  \
        uint32_t name##_set;            \
        uint32_t name##_clr;            \
-       uint32_t name##_tog;
+       uint32_t name##_tog
+
+#define __reg_32(name)                 \
+       uint32_t name;                  \
+       uint32_t reserved_##name[3]
 
 struct mxs_register_8 {
-       __mxs_reg_8(reg)
+       __mxs_reg_8(reg);
 };
 
 struct mxs_register_32 {
-       __mxs_reg_32(reg)
+       __mxs_reg_32(reg);
 };
 
-#define        mxs_reg_8(name)                         \
+#define        mxs_reg_8(name)                                 \
        union {                                         \
-               struct { __mxs_reg_8(name) };           \
+               struct { __mxs_reg_8(name); };          \
                struct mxs_register_8 name##_reg;       \
-       };
+       }
 
-#define        mxs_reg_32(name)                                \
+#define        mxs_reg_32(name);                               \
        union {                                         \
-               struct { __mxs_reg_32(name) };          \
+               struct { __mxs_reg_32(name); };         \
                struct mxs_register_32 name##_reg;      \
-       };
+       }
+
+#define        reg_32(name)                                    \
+       struct { __reg_32(name); }
+#endif
 
 #endif /* __MXS_REGS_COMMON_H__ */
index b93bfe55cb56b440224f6e723fde16b09caaded5..642864f3cfdcdc14b16a9cd323a502033dcab974 100644 (file)
 #include <asm/imx-common/regs-common.h>
 
 #ifndef        __ASSEMBLY__
-struct mxs_gpmi_regs {
-       mxs_reg_32(hw_gpmi_ctrl0)
-       mxs_reg_32(hw_gpmi_compare)
-       mxs_reg_32(hw_gpmi_eccctrl)
-       mxs_reg_32(hw_gpmi_ecccount)
-       mxs_reg_32(hw_gpmi_payload)
-       mxs_reg_32(hw_gpmi_auxiliary)
-       mxs_reg_32(hw_gpmi_ctrl1)
-       mxs_reg_32(hw_gpmi_timing0)
-       mxs_reg_32(hw_gpmi_timing1)
+struct gpmi_regs {
+       mxs_reg_32(hw_gpmi_ctrl0);
+       mxs_reg_32(hw_gpmi_compare);
+       mxs_reg_32(hw_gpmi_eccctrl);
+       mxs_reg_32(hw_gpmi_ecccount);
+       mxs_reg_32(hw_gpmi_payload);
+       mxs_reg_32(hw_gpmi_auxiliary);
+       mxs_reg_32(hw_gpmi_ctrl1);
+       mxs_reg_32(hw_gpmi_timing0);
+       mxs_reg_32(hw_gpmi_timing1);
 
        uint32_t        reserved[4];
 
-       mxs_reg_32(hw_gpmi_data)
-       mxs_reg_32(hw_gpmi_stat)
-       mxs_reg_32(hw_gpmi_debug)
-       mxs_reg_32(hw_gpmi_version)
+       mxs_reg_32(hw_gpmi_data);
+       mxs_reg_32(hw_gpmi_stat);
+       mxs_reg_32(hw_gpmi_debug);
+       mxs_reg_32(hw_gpmi_version);
 };
 #endif
 
+#define GPMI_BASE_ADDRESS                              MXS_GPMI_BASE
+
 #define        GPMI_CTRL0_SFTRST                               (1 << 31)
 #define        GPMI_CTRL0_CLKGATE                              (1 << 30)
 #define        GPMI_CTRL0_RUN                                  (1 << 29)
index 89f22946895301b09a183ead75503ae4dff0f1b2..f5096dc0fda8fe255bfb0407fcf21c06df20e078 100644 (file)
@@ -155,7 +155,7 @@ void flush_l3_cache(void);
 static inline unsigned int get_cr(void)
 {
        unsigned int val;
-       asm("mrc p15, 0, %0, c1, c0, 0  @ get CR" : "=r" (val) : : "cc");
+       asm volatile("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
        return val;
 }
 
index b0c26e5d689318195343152926eac50699cdd3d7..faafc627cd907d22bb9b805010964d9198e32815 100644 (file)
 #include <asm/arch/mb86r0x.h>
 #endif
 #if defined(CONFIG_MX25) || defined(CONFIG_MX27) || defined(CONFIG_MX35) \
-       || defined(CONFIG_MX51) || defined(CONFIG_MX53)
+       || defined(CONFIG_MX51) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
 #include <asm/arch/imx-regs.h>
 #endif
+#if defined(CONFIG_MX6)
+#include <asm/arch/crm_regs.h>
+#endif
 
 int main(void)
 {
@@ -243,6 +246,43 @@ int main(void)
        DEFINE(PLL_DP_HFS_MFD, offsetof(struct dpll, dp_hfs_mfd));
        DEFINE(PLL_DP_HFS_MFN, offsetof(struct dpll, dp_hfs_mfn));
 #endif
+#if defined(CONFIG_MX6)
+       DEFINE(CCM_CCR, offsetof(struct mxc_ccm_reg, ccr));
+       DEFINE(CCM_CCDR, offsetof(struct mxc_ccm_reg, ccdr));
+       DEFINE(CCM_CSR, offsetof(struct mxc_ccm_reg, csr));
+       DEFINE(CCM_CCSR, offsetof(struct mxc_ccm_reg, ccsr));
+       DEFINE(CCM_CACRR, offsetof(struct mxc_ccm_reg, cacrr));
+       DEFINE(CCM_CBCDR, offsetof(struct mxc_ccm_reg, cbcdr));
+       DEFINE(CCM_CBCMR, offsetof(struct mxc_ccm_reg, cbcmr));
+       DEFINE(CCM_CSCMR1, offsetof(struct mxc_ccm_reg, cscmr1));
+       DEFINE(CCM_CSCMR2, offsetof(struct mxc_ccm_reg, cscmr2));
+       DEFINE(CCM_CSCDR1, offsetof(struct mxc_ccm_reg, cscdr1));
+       DEFINE(CCM_CS1CDR, offsetof(struct mxc_ccm_reg, cs1cdr));
+       DEFINE(CCM_CS2CDR, offsetof(struct mxc_ccm_reg, cs2cdr));
+       DEFINE(CCM_CDCDR, offsetof(struct mxc_ccm_reg, cdcdr));
+       DEFINE(CCM_CHSCCDR, offsetof(struct mxc_ccm_reg, chsccdr));
+       DEFINE(CCM_CSCDR2, offsetof(struct mxc_ccm_reg, cscdr2));
+       DEFINE(CCM_CSCDR3, offsetof(struct mxc_ccm_reg, cscdr3));
+       DEFINE(CCM_CSCDR4, offsetof(struct mxc_ccm_reg, cscdr4));
+       DEFINE(CCM_CDHIPR, offsetof(struct mxc_ccm_reg, cdhipr));
+       DEFINE(CCM_CDCR, offsetof(struct mxc_ccm_reg, cdcr));
+       DEFINE(CCM_CTOR, offsetof(struct mxc_ccm_reg, ctor));
+       DEFINE(CCM_CLPCR, offsetof(struct mxc_ccm_reg, clpcr));
+       DEFINE(CCM_CISR, offsetof(struct mxc_ccm_reg, cisr));
+       DEFINE(CCM_CIMR, offsetof(struct mxc_ccm_reg, cimr));
+       DEFINE(CCM_CCOSR, offsetof(struct mxc_ccm_reg, ccosr));
+       DEFINE(CCM_CGPR, offsetof(struct mxc_ccm_reg, cgpr));
+       DEFINE(CCM_CCGR0, offsetof(struct mxc_ccm_reg, CCGR0));
+       DEFINE(CCM_CCGR1, offsetof(struct mxc_ccm_reg, CCGR1));
+       DEFINE(CCM_CCGR2, offsetof(struct mxc_ccm_reg, CCGR2));
+       DEFINE(CCM_CCGR3, offsetof(struct mxc_ccm_reg, CCGR3));
+       DEFINE(CCM_CCGR4, offsetof(struct mxc_ccm_reg, CCGR4));
+       DEFINE(CCM_CCGR5, offsetof(struct mxc_ccm_reg, CCGR5));
+       DEFINE(CCM_CCGR6, offsetof(struct mxc_ccm_reg, CCGR6));
+       DEFINE(CCM_CCGR7, offsetof(struct mxc_ccm_reg, CCGR7));
+       DEFINE(CCM_CMEOR, offsetof(struct mxc_ccm_reg, cmeor));
 
+       DEFINE(ANATOP_PLL_ENET, offsetof(struct anatop_regs, pll_enet));
+#endif
        return 0;
 }
index f6062557e6677fe0636520f9d7f76a9eedfc8d50..3c0ba079d3d864c517040023e83eebf07ff170bb 100644 (file)
@@ -509,7 +509,7 @@ void board_init_r(gd_t *id, ulong dest_addr)
        debug("monitor flash len: %08lX\n", monitor_flash_len);
        board_init();   /* Setup chipselects */
        /*
-        * TODO: printing of the clock inforamtion of the board is now
+        * TODO: printing of the clock information of the board is now
         * implemented as part of bdinfo command. Currently only support for
         * davinci SOC's is added. Remove this check once all the board
         * implement this.
index 0291afa7bd531088f441808e9f9767cceb4d774b..751abe4e3c83f50f5fb5ad121c91f4603bd5051c 100644 (file)
@@ -22,16 +22,6 @@ __weak void arm_init_domains(void)
 {
 }
 
-static void cp_delay (void)
-{
-       volatile int i;
-
-       /* copro seems to need some delay between reading and writing */
-       for (i = 0; i < 100; i++)
-               nop();
-       asm volatile("" : : : "memory");
-}
-
 void set_section_dcache(int section, enum dcache_option option)
 {
        u32 *page_table = (u32 *)gd->arch.tlb_addr;
@@ -96,18 +86,20 @@ static inline void mmu_setup(void)
                dram_bank_mmu_setup(i);
        }
 
-       /* Copy the page table address to cp15 */
-       asm volatile("mcr p15, 0, %0, c2, c0, 0"
-                    : : "r" (gd->arch.tlb_addr) : "memory");
-       /* Set the access control to all-supervisor */
-       asm volatile("mcr p15, 0, %0, c3, c0, 0"
-                    : : "r" (~0));
+       asm volatile(
+               /* Copy the page table address to cp15 */
+               "mcr p15, 0, %0, c2, c0, 0\n"
+               /* Set the access control to all-supervisor */
+               "mcr p15, 0, %1, c3, c0, 0\n"
+               :
+               : "r"(gd->arch.tlb_addr), "r"(~0)
+               : "memory"
+               );
 
        arm_init_domains();
 
        /* and enable the mmu */
        reg = get_cr(); /* get control reg. */
-       cp_delay();
        set_cr(reg | CR_M);
 }
 
@@ -125,7 +117,6 @@ static void cache_enable(uint32_t cache_bit)
        if ((cache_bit == CR_C) && !mmu_enabled())
                mmu_setup();
        reg = get_cr(); /* get control reg. */
-       cp_delay();
        set_cr(reg | cache_bit);
 }
 
@@ -135,7 +126,6 @@ static void cache_disable(uint32_t cache_bit)
        uint32_t reg;
 
        reg = get_cr();
-       cp_delay();
 
        if (cache_bit == CR_C) {
                /* if cache isn;t enabled no need to disable */
@@ -145,7 +135,6 @@ static void cache_disable(uint32_t cache_bit)
                cache_bit |= CR_M;
        }
        reg = get_cr();
-       cp_delay();
        if (cache_bit == (CR_C | CR_M))
                flush_dcache_all();
        set_cr(reg & ~cache_bit);
index 74cfde637c1c433f3f834cdfbdac48b05ff78b6a..20c708a7c3edfe7239aa673205e61c65602031e8 100644 (file)
@@ -26,10 +26,12 @@ __weak void flush_cache(unsigned long start, unsigned long size)
 
 #ifdef CONFIG_CPU_ARM926EJS
 #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
-       /* test and clean, page 2-23 of arm926ejs manual */
-       asm("0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n" : : : "memory");
-       /* disable write buffer as well (page 2-22) */
-       asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
+       asm(
+               /* test and clean, page 2-23 of arm926ejs manual */
+               "0: mrc p15, 0, r15, c7, c10, 3\n\t" "bne 0b\n"
+               /* flush write buffer as well (page 2-22) */
+               "mcr p15, 0, %0, c7, c10, 4" : : "r"(0) : "memory"
+               );
 #endif
 #endif /* CONFIG_CPU_ARM926EJS */
        return;
index 22df3e5b832c31a86cab5bbd2902b83c34a84033..8a774512b6d8a9429a8b60b53fd3911fc3811bb0 100644 (file)
@@ -62,9 +62,9 @@ ENTRY(_main)
  */
 
 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
-       ldr     sp, =(CONFIG_SPL_STACK)
+       ldr     sp, =CONFIG_SPL_STACK
 #else
-       ldr     sp, =(CONFIG_SYS_INIT_SP_ADDR)
+       ldr     sp, =CONFIG_SYS_INIT_SP_ADDR
 #endif
        bic     sp, sp, #7      /* 8-byte alignment for ABI compliance */
        mov     r2, sp
index 4dacfd941f6dd220cfa2f5d2a7ae006b10d628a2..3d6e5a3498cede8fd823fa340ea865668d4e53ff 100644 (file)
@@ -135,12 +135,20 @@ void show_regs (struct pt_regs *regs)
        "UK12_32",      "UK13_32",      "UK14_32",      "SYS_32",
        };
 
-       flags = condition_codes (regs);
-
-       printf ("pc : [<%08lx>]    lr : [<%08lx>]\n"
-               "sp : %08lx  ip : %08lx  fp : %08lx\n",
-               instruction_pointer (regs),
-               regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+       flags = condition_codes(regs);
+
+       if (gd->flags & GD_FLG_RELOC)
+               printf ("pc : [<%08lx>] (pre-reloc: [<%08lx>]) lr : [<%08lx>]\n"
+                       "sp : %08lx  ip : %08lx  fp : %08lx\n",
+                       instruction_pointer(regs),
+                       instruction_pointer(regs) - gd->reloc_off,
+                       regs->ARM_lr, regs->ARM_sp,
+                       regs->ARM_ip, regs->ARM_fp);
+       else
+               printf ("pc : [<%08lx>] lr : [<%08lx>]\n"
+                       "sp : %08lx  ip : %08lx  fp : %08lx\n",
+                       instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp,
+                       regs->ARM_ip, regs->ARM_fp);
        printf ("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
                regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
        printf ("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
@@ -158,9 +166,17 @@ void show_regs (struct pt_regs *regs)
                thumb_mode (regs) ? " (T)" : "");
 }
 
+/* fixup PC to point to instruction leading to exception */
+static inline void fixup_pc(struct pt_regs *regs, int offset)
+{
+       uint32_t pc = instruction_pointer(regs) + offset;
+       regs->ARM_pc = pc | (regs->ARM_pc & PCMASK);
+}
+
 void do_undefined_instruction (struct pt_regs *pt_regs)
 {
        printf ("undefined instruction\n");
+       fixup_pc(pt_regs, -4);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -168,6 +184,7 @@ void do_undefined_instruction (struct pt_regs *pt_regs)
 void do_software_interrupt (struct pt_regs *pt_regs)
 {
        printf ("software interrupt\n");
+       fixup_pc(pt_regs, -4);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -175,6 +192,7 @@ void do_software_interrupt (struct pt_regs *pt_regs)
 void do_prefetch_abort (struct pt_regs *pt_regs)
 {
        printf ("prefetch abort\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -182,6 +200,7 @@ void do_prefetch_abort (struct pt_regs *pt_regs)
 void do_data_abort (struct pt_regs *pt_regs)
 {
        printf ("data abort\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -189,6 +208,7 @@ void do_data_abort (struct pt_regs *pt_regs)
 void do_not_used (struct pt_regs *pt_regs)
 {
        printf ("not used\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -196,6 +216,7 @@ void do_not_used (struct pt_regs *pt_regs)
 void do_fiq (struct pt_regs *pt_regs)
 {
        printf ("fast interrupt request\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
@@ -204,6 +225,7 @@ void do_fiq (struct pt_regs *pt_regs)
 void do_irq (struct pt_regs *pt_regs)
 {
        printf ("interrupt request\n");
+       fixup_pc(pt_regs, -8);
        show_regs (pt_regs);
        bad_mode ();
 }
index 9a95f085044ade0c8f62fe489263c455b08df221..18d3e7eeffec16f71f0e5116d0bd66ee9e74eaea 100644 (file)
@@ -37,7 +37,5 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        reset_misc();
        reset_cpu(0);
-
-       /*NOTREACHED*/
-       return 0;
+       hang();
 }
index 49238ed21ed83766fe207c1060cef4e5b2d4257d..1b51f003f35efb9bfb08c7cee1f895bfec0564fb 100644 (file)
@@ -117,7 +117,11 @@ fiq:
 /* IRQ stack memory (calculated at run-time) + 8 bytes */
 .globl IRQ_STACK_START_IN
 IRQ_STACK_START_IN:
+#ifndef IRAM_BASE_ADDR
        .word   0x0badc0de
+#else
+       .word   IRAM_BASE_ADDR + 0x20
+#endif
 
 #ifdef CONFIG_USE_IRQ
 /* IRQ stack memory (calculated at run-time) */
index e8ea256be0c5c8d94198a15d4ed5e0da1cfead06..c84c220047f3ab82cfcd3ac75cfff002f3e55ea7 100644 (file)
@@ -144,7 +144,7 @@ static iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_SD3_DAT5__GPIO7_IO00    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_SD3_DAT5__GPIO7_IO00, /* CD */
 };
 
 static iomux_v3_cfg_t const usdhc4_pads[] = {
@@ -154,7 +154,7 @@ static iomux_v3_cfg_t const usdhc4_pads[] = {
        MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D6__GPIO2_IO06    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_D6__GPIO2_IO06, /* CD */
 };
 
 static iomux_v3_cfg_t const enet_pads1[] = {
@@ -168,20 +168,20 @@ static iomux_v3_cfg_t const enet_pads1[] = {
        MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* pin 35 - 1 (PHY_AD2) on reset */
-       MX6_PAD_RGMII_RXC__GPIO6_IO30           | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RXC__GPIO6_IO30,
        /* pin 32 - 1 - (MODE0) all */
-       MX6_PAD_RGMII_RD0__GPIO6_IO25           | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD0__GPIO6_IO25,
        /* pin 31 - 1 - (MODE1) all */
-       MX6_PAD_RGMII_RD1__GPIO6_IO27           | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD1__GPIO6_IO27,
        /* pin 28 - 1 - (MODE2) all */
-       MX6_PAD_RGMII_RD2__GPIO6_IO28           | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD2__GPIO6_IO28,
        /* pin 27 - 1 - (MODE3) all */
-       MX6_PAD_RGMII_RD3__GPIO6_IO29           | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RD3__GPIO6_IO29,
        /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
-       MX6_PAD_RGMII_RX_CTL__GPIO6_IO24        | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_RGMII_RX_CTL__GPIO6_IO24,
        /* pin 42 PHY nRST */
-       MX6_PAD_EIM_D23__GPIO3_IO23             | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_ENET_RXD0__GPIO1_IO27           | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_D23__GPIO3_IO23,
+       MX6_PAD_ENET_RXD0__GPIO1_IO27,
 };
 
 static iomux_v3_cfg_t const enet_pads2[] = {
@@ -252,7 +252,7 @@ static void setup_iomux_enet(void)
 }
 
 static iomux_v3_cfg_t const usb_pads[] = {
-       MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_GPIO_17__GPIO7_IO12,
 };
 
 static void setup_iomux_uart(void)
@@ -345,7 +345,7 @@ int board_spi_cs_gpio(unsigned bus, unsigned cs)
 
 static iomux_v3_cfg_t const ecspi1_pads[] = {
        /* SS1 */
-       MX6_PAD_EIM_D19__GPIO3_IO19  | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_D19__GPIO3_IO19,
        MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
@@ -420,11 +420,11 @@ static void setup_buttons(void)
 
 static iomux_v3_cfg_t const backlight_pads[] = {
        /* Backlight on RGB connector: J15 */
-       MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_SD1_DAT3__GPIO1_IO21,
 #define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
 
        /* Backlight on LVDS connector: J6 */
-       MX6_PAD_SD1_CMD__GPIO1_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_SD1_CMD__GPIO1_IO18,
 #define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
 };
 
index 749253429b15949de3b02e7330fcc3553c9c6b05..ac64bcc9118a5bdd11977eb71420651548ed060b 100644 (file)
@@ -60,7 +60,7 @@ iomux_v3_cfg_t const usdhc4_pads[] = {
        MX6_PAD_SD4_DAT5__SD4_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD4_DAT6__SD4_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD4_DAT7__SD4_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D6__GPIO2_IO06    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_D6__GPIO2_IO06, /* CD */
 };
 
 static void setup_iomux_uart(void)
index 5a1010e59550a4c65d9e2fc2ad3922ae0e5f9660..8044a717d66ec16d03b542b6e79d0b932b24daac 100644 (file)
@@ -204,3 +204,53 @@ void board_init_ll(const uint32_t arg, const uint32_t *resptr)
 {
        mxs_common_spl_init(arg, resptr, iomux_setup, ARRAY_SIZE(iomux_setup));
 }
+
+static uint32_t dram_vals[] = {
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00010101, 0x01010101, 0x000f0f01, 0x0f02020a,
+       0x00000000, 0x00010101, 0x00000100, 0x00000100, 0x00000000,
+       0x00000002, 0x01010000, 0x05060302, 0x06005003, 0x0a0000c8,
+       0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612, 0x02030202,
+       0x00c8001c, 0x00000000, 0x00000000, 0x00012100, 0xffff0303,
+       0x00012100, 0xffff0303, 0x00012100, 0xffff0303, 0x00012100,
+       0xffff0303, 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000612, 0x01000F02, 0x06120612, 0x00000200,
+       0x00020007, 0xf5014b27, 0xf5014b27, 0xf5014b27, 0xf5014b27,
+       0x07000300, 0x07000300, 0x07000300, 0x07000300, 0x00000006,
+       0x00000000, 0x00000000, 0x01000000, 0x01020408, 0x08040201,
+       0x000f1133, 0x00000000, 0x00001f04, 0x00001f04, 0x00001f04,
+       0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x00000000, 0x00010000, 0x00020304, 0x00000004,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       0x00000000, 0x01010000, 0x01000000, 0x03030000, 0x00010303,
+       0x01020202, 0x00000000, 0x02040303, 0x21002103, 0x00061200,
+       0x06120612, 0x04320432, 0x04320432, 0x00040004, 0x00040004,
+       0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010001
+};
+
+void mx28_ddr2_setup(void)
+{
+       int i;
+
+       serial_puts("\n");
+       for (i = 0; i < ARRAY_SIZE(dram_vals); i++)
+               writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
+}
index 98ccdb785b3498fa15406f628e84cbbd1da859aa..abe56c9e31da2b08cf34cb043af04e9ca7030500 100644 (file)
@@ -59,7 +59,7 @@ iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_CS0__GPIO6_IO11  | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_CS0__GPIO6_IO11, /* CD */
 };
 
 iomux_v3_cfg_t const usdhc4_pads[] = {
@@ -219,8 +219,8 @@ int board_eth_init(bd_t *bis)
 #define UCTRL_PWR_POL          (1 << 9)
 
 static iomux_v3_cfg_t const usb_otg_pads[] = {
-       MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_D22__USB_OTG_PWR,
+       MX6_PAD_GPIO_1__USB_OTG_ID,
 };
 
 static void setup_usb(void)
index 59387ffaaa7e7960e625f3b8e0833f7f297dee23..c7a790f527fd7465c9476e0dfb373898daf5a939 100644 (file)
@@ -125,11 +125,11 @@ static struct i2c_pads_info i2c_pad_info2 = {
 #endif
 
 static iomux_v3_cfg_t const i2c3_pads[] = {
-       MX6_PAD_EIM_A24__GPIO5_IO04             | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_A24__GPIO5_IO04,
 };
 
 static iomux_v3_cfg_t const port_exp[] = {
-       MX6_PAD_SD2_DAT0__GPIO1_IO15            | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_SD2_DAT0__GPIO1_IO15,
 };
 
 /*Define for building port exp gpio, pin starts from 0*/
@@ -211,9 +211,9 @@ static iomux_v3_cfg_t const eimnor_pads[] = {
        MX6_PAD_EIM_A21__EIM_ADDR21     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
        MX6_PAD_EIM_A22__EIM_ADDR22     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
        MX6_PAD_EIM_A23__EIM_ADDR23     | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL),
-       MX6_PAD_EIM_OE__EIM_OE_B        | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_EIM_RW__EIM_RW          | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_EIM_CS0__EIM_CS0_B      | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_OE__EIM_OE_B,
+       MX6_PAD_EIM_RW__EIM_RW,
+       MX6_PAD_EIM_CS0__EIM_CS0_B,
 };
 
 static void eimnor_cs_setup(void)
@@ -256,7 +256,7 @@ static iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT6__SD3_DATA6     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT7__SD3_DATA7     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_GPIO_18__SD3_VSELECT | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_CS2__GPIO6_IO15   | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_NANDF_CS2__GPIO6_IO15,
 };
 
 static void setup_iomux_uart(void)
@@ -565,7 +565,7 @@ int checkboard(void)
 #define USB_OTG_PWR       PORTEXP_IO_NR(0x34, 1)
 
 iomux_v3_cfg_t const usb_otg_pads[] = {
-       MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_ENET_RX_ER__USB_OTG_ID,
 };
 
 int board_ehci_hcd_init(int port)
diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
new file mode 100644 (file)
index 0000000..91ac10d
--- /dev/null
@@ -0,0 +1,832 @@
+/*
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+ 
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/mx6q_pins.h>
+#include <asm/errno.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/mxc_i2c.h>
+#include <asm/imx-common/boot_mode.h>
+#include <mmc.h>
+#include <fsl_esdhc.h>
+#include <malloc.h>
+#include <micrel.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <linux/fb.h>
+#include <ipu_pixfmt.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/mxc_hdmi.h>
+#include <i2c.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                  \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
+       PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP |                   \
+       PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm |                 \
+       PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                  \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED |                \
+       PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
+
+#define BUTTON_PAD_CTRL (PAD_CTL_PUS_100K_UP |                 \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define I2C_PAD_CTRL   (PAD_CTL_PUS_100K_UP |                  \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |   \
+       PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+
+int dram_init(void)
+{
+       gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
+
+       return 0;
+}
+
+iomux_v3_cfg_t const uart1_pads[] = {
+       MX6_PAD_SD3_DAT6__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+       MX6_PAD_SD3_DAT7__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+iomux_v3_cfg_t const uart2_pads[] = {
+       MX6_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+       MX6_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
+
+/* I2C1, SGTL5000 */
+struct i2c_pads_info i2c_pad_info0 = {
+       .scl = {
+               .i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC,
+               .gpio_mode = MX6_PAD_EIM_D21__GPIO_3_21 | PC,
+               .gp = IMX_GPIO_NR(3, 21)
+       },
+       .sda = {
+               .i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC,
+               .gpio_mode = MX6_PAD_EIM_D28__GPIO_3_28 | PC,
+               .gp = IMX_GPIO_NR(3, 28)
+       }
+};
+
+/* I2C2 Camera, MIPI */
+struct i2c_pads_info i2c_pad_info1 = {
+       .scl = {
+               .i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
+               .gpio_mode = MX6_PAD_KEY_COL3__GPIO_4_12 | PC,
+               .gp = IMX_GPIO_NR(4, 12)
+       },
+       .sda = {
+               .i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
+               .gpio_mode = MX6_PAD_KEY_ROW3__GPIO_4_13 | PC,
+               .gp = IMX_GPIO_NR(4, 13)
+       }
+};
+
+/* I2C3, J15 - RGB connector */
+struct i2c_pads_info i2c_pad_info2 = {
+       .scl = {
+               .i2c_mode = MX6_PAD_GPIO_5__I2C3_SCL | PC,
+               .gpio_mode = MX6_PAD_GPIO_5__GPIO_1_5 | PC,
+               .gp = IMX_GPIO_NR(1, 5)
+       },
+       .sda = {
+               .i2c_mode = MX6_PAD_GPIO_16__I2C3_SDA | PC,
+               .gpio_mode = MX6_PAD_GPIO_16__GPIO_7_11 | PC,
+               .gp = IMX_GPIO_NR(7, 11)
+       }
+};
+
+iomux_v3_cfg_t const usdhc3_pads[] = {
+       MX6_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT5__GPIO_7_0, /* CD */
+};
+
+iomux_v3_cfg_t const usdhc4_pads[] = {
+       MX6_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_NANDF_D6__GPIO_2_6, /* CD */
+};
+
+iomux_v3_cfg_t const enet_pads1[] = {
+       MX6_PAD_ENET_MDIO__ENET_MDIO            | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_ENET_MDC__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TXC__ENET_RGMII_TXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD0__ENET_RGMII_TD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD1__ENET_RGMII_TD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD2__ENET_RGMII_TD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD3__ENET_RGMII_TD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       /* pin 35 - 1 (PHY_AD2) on reset */
+       MX6_PAD_RGMII_RXC__GPIO_6_30,
+       /* pin 32 - 1 - (MODE0) all */
+       MX6_PAD_RGMII_RD0__GPIO_6_25,
+       /* pin 31 - 1 - (MODE1) all */
+       MX6_PAD_RGMII_RD1__GPIO_6_27,
+       /* pin 28 - 1 - (MODE2) all */
+       MX6_PAD_RGMII_RD2__GPIO_6_28,
+       /* pin 27 - 1 - (MODE3) all */
+       MX6_PAD_RGMII_RD3__GPIO_6_29,
+       /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
+       MX6_PAD_RGMII_RX_CTL__GPIO_6_24,
+       /* pin 42 PHY nRST */
+       MX6_PAD_EIM_D23__GPIO_3_23,
+};
+
+iomux_v3_cfg_t const enet_pads2[] = {
+       MX6_PAD_RGMII_RXC__ENET_RGMII_RXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD0__ENET_RGMII_RD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD1__ENET_RGMII_RD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD2__ENET_RGMII_RD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
+};
+
+/* Button assignments for J14 */
+static iomux_v3_cfg_t const button_pads[] = {
+       /* Menu */
+       MX6_PAD_NANDF_D1__GPIO_2_1      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Back */
+       MX6_PAD_NANDF_D2__GPIO_2_2      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Labelled Search (mapped to Power under Android) */
+       MX6_PAD_NANDF_D3__GPIO_2_3      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Home */
+       MX6_PAD_NANDF_D4__GPIO_2_4      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Volume Down */
+       MX6_PAD_GPIO_19__GPIO_4_5       | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+       /* Volume Up */
+       MX6_PAD_GPIO_18__GPIO_7_13      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
+};
+
+static void setup_iomux_enet(void)
+{
+       gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
+       gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
+       imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
+       gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
+
+       /* Need delay 10ms according to KSZ9021 spec */
+       udelay(1000 * 10);
+       gpio_set_value(IMX_GPIO_NR(3, 23), 1);
+
+       imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
+}
+
+iomux_v3_cfg_t const usb_pads[] = {
+       MX6_PAD_GPIO_17__GPIO_7_12,
+};
+
+static void setup_iomux_uart(void)
+{
+       imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
+       imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
+}
+
+#ifdef CONFIG_USB_EHCI_MX6
+int board_ehci_hcd_init(int port)
+{
+       imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
+
+       /* Reset USB hub */
+       gpio_direction_output(IMX_GPIO_NR(7, 12), 0);
+       mdelay(2);
+       gpio_set_value(IMX_GPIO_NR(7, 12), 1);
+
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+struct fsl_esdhc_cfg usdhc_cfg[2] = {
+       {USDHC3_BASE_ADDR},
+       {USDHC4_BASE_ADDR},
+};
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+       int ret;
+
+       if (cfg->esdhc_base == USDHC3_BASE_ADDR) {
+               gpio_direction_input(IMX_GPIO_NR(7, 0));
+               ret = !gpio_get_value(IMX_GPIO_NR(7, 0));
+       } else {
+               gpio_direction_input(IMX_GPIO_NR(2, 6));
+               ret = !gpio_get_value(IMX_GPIO_NR(2, 6));
+       }
+
+       return ret;
+}
+
+int board_mmc_init(bd_t *bis)
+{
+       s32 status = 0;
+       u32 index = 0;
+
+       usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+       usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+
+       usdhc_cfg[0].max_bus_width = 4;
+       usdhc_cfg[1].max_bus_width = 4;
+
+       for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
+               switch (index) {
+               case 0:
+                       imx_iomux_v3_setup_multiple_pads(
+                               usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+                       break;
+               case 1:
+                       imx_iomux_v3_setup_multiple_pads(
+                               usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
+                       break;
+               default:
+                       printf("Warning: you configured more USDHC controllers"
+                              "(%d) then supported by the board (%d)\n",
+                              index + 1, CONFIG_SYS_FSL_USDHC_NUM);
+                       return status;
+               }
+
+               status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
+       }
+
+       return status;
+}
+#endif
+
+#ifdef CONFIG_MXC_SPI
+iomux_v3_cfg_t const ecspi1_pads[] = {
+       /* SS1 */
+       MX6_PAD_EIM_D19__GPIO_3_19   | MUX_PAD_CTRL(SPI_PAD_CTRL),
+       MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
+       MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
+       MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
+};
+
+void setup_spi(void)
+{
+       imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
+                                        ARRAY_SIZE(ecspi1_pads));
+}
+#endif
+
+int board_phy_config(struct phy_device *phydev)
+{
+       /* min rx data delay */
+       ksz9021_phy_extended_write(phydev,
+                       MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
+       /* min tx data delay */
+       ksz9021_phy_extended_write(phydev,
+                       MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
+       /* max rx/tx clock delay, min rx/tx control */
+       ksz9021_phy_extended_write(phydev,
+                       MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
+       if (phydev->drv->config)
+               phydev->drv->config(phydev);
+
+       return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+       uint32_t base = IMX_FEC_BASE;
+       struct mii_dev *bus = NULL;
+       struct phy_device *phydev = NULL;
+       int ret;
+
+       setup_iomux_enet();
+
+#ifdef CONFIG_FEC_MXC
+       bus = fec_get_miibus(base, -1);
+       if (!bus)
+               return 0;
+       /* scan phy 4,5,6,7 */
+       phydev = phy_find_by_mask(bus, (0xf << 4), PHY_INTERFACE_MODE_RGMII);
+       if (!phydev) {
+               free(bus);
+               return 0;
+       }
+       printf("using phy at %d\n", phydev->addr);
+       ret  = fec_probe(bis, -1, base, bus, phydev);
+       if (ret) {
+               printf("FEC MXC: %s:failed\n", __func__);
+               free(phydev);
+               free(bus);
+       }
+#endif
+       return 0;
+}
+
+static void setup_buttons(void)
+{
+       imx_iomux_v3_setup_multiple_pads(button_pads,
+                                        ARRAY_SIZE(button_pads));
+}
+
+#ifdef CONFIG_CMD_SATA
+
+int setup_sata(void)
+{
+       struct iomuxc *const iomuxc_regs = (void *)IOMUXC_BASE_ADDR;
+       int ret = enable_sata_clock();
+
+       if (ret)
+               return ret;
+
+       clrsetbits_le32(&iomuxc_regs->gpr[13],
+                       IOMUXC_GPR13_SATA_MASK,
+                       IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P0DB
+                       |IOMUXC_GPR13_SATA_PHY_7_SATA2M
+                       |IOMUXC_GPR13_SATA_SPEED_3G
+                       |(3<<IOMUXC_GPR13_SATA_PHY_6_SHIFT)
+                       |IOMUXC_GPR13_SATA_SATA_PHY_5_SS_DISABLED
+                       |IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_9_16
+                       |IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P00_DB
+                       |IOMUXC_GPR13_SATA_PHY_2_TX_1P104V
+                       |IOMUXC_GPR13_SATA_PHY_1_SLOW);
+
+       return 0;
+}
+#endif
+
+#if defined(CONFIG_VIDEO_IPUV3)
+
+static iomux_v3_cfg_t const backlight_pads[] = {
+       /* Backlight on RGB connector: J15 */
+       MX6_PAD_SD1_DAT3__GPIO_1_21,
+#define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
+
+       /* Backlight on LVDS connector: J6 */
+       MX6_PAD_SD1_CMD__GPIO_1_18,
+#define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
+};
+
+static iomux_v3_cfg_t const rgb_pads[] = {
+       MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+       MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+       MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+       MX6_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+       MX6_PAD_DI0_PIN4__GPIO_4_20,
+       MX6_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+       MX6_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+       MX6_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+       MX6_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+       MX6_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+       MX6_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+       MX6_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+       MX6_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+       MX6_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+       MX6_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+       MX6_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+       MX6_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+       MX6_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+       MX6_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+       MX6_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+       MX6_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+       MX6_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+       MX6_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+       MX6_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+       MX6_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+       MX6_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+       MX6_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+       MX6_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+       MX6_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+};
+
+struct display_info_t {
+       int     bus;
+       int     addr;
+       int     pixfmt;
+       int     (*detect)(struct display_info_t const *dev);
+       void    (*enable)(struct display_info_t const *dev);
+       struct  fb_videomode mode;
+};
+
+
+static int detect_hdmi(struct display_info_t const *dev)
+{
+       struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+       return readb(&hdmi->phy_stat0) & HDMI_PHY_HPD;
+}
+
+static void enable_hdmi(struct display_info_t const *dev)
+{
+       struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+       u8 reg;
+       printf("%s: setup HDMI monitor\n", __func__);
+       reg = readb(&hdmi->phy_conf0);
+       reg |= HDMI_PHY_CONF0_PDZ_MASK;
+       writeb(reg, &hdmi->phy_conf0);
+
+       udelay(3000);
+       reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
+       writeb(reg, &hdmi->phy_conf0);
+       udelay(3000);
+       reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
+       writeb(reg, &hdmi->phy_conf0);
+       writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
+}
+
+static int detect_i2c(struct display_info_t const *dev)
+{
+       return ((0 == i2c_set_bus_num(dev->bus))
+               &&
+               (0 == i2c_probe(dev->addr)));
+}
+
+static void enable_lvds(struct display_info_t const *dev)
+{
+       struct iomuxc *iomux = (struct iomuxc *)
+                               IOMUXC_BASE_ADDR;
+       u32 reg = readl(&iomux->gpr[2]);
+       reg |= IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT;
+       writel(reg, &iomux->gpr[2]);
+       gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
+}
+
+static void enable_rgb(struct display_info_t const *dev)
+{
+       imx_iomux_v3_setup_multiple_pads(
+               rgb_pads,
+                ARRAY_SIZE(rgb_pads));
+       gpio_direction_output(RGB_BACKLIGHT_GP, 1);
+}
+
+static struct display_info_t const displays[] = {{
+       .bus    = -1,
+       .addr   = 0,
+       .pixfmt = IPU_PIX_FMT_RGB24,
+       .detect = detect_hdmi,
+       .enable = enable_hdmi,
+       .mode   = {
+               .name           = "HDMI",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = 15385,
+               .left_margin    = 220,
+               .right_margin   = 40,
+               .upper_margin   = 21,
+               .lower_margin   = 7,
+               .hsync_len      = 60,
+               .vsync_len      = 10,
+               .sync           = FB_SYNC_EXT,
+               .vmode          = FB_VMODE_NONINTERLACED
+} }, {
+       .bus    = 2,
+       .addr   = 0x4,
+       .pixfmt = IPU_PIX_FMT_LVDS666,
+       .detect = detect_i2c,
+       .enable = enable_lvds,
+       .mode   = {
+               .name           = "Hannstar-XGA",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = 15385,
+               .left_margin    = 220,
+               .right_margin   = 40,
+               .upper_margin   = 21,
+               .lower_margin   = 7,
+               .hsync_len      = 60,
+               .vsync_len      = 10,
+               .sync           = FB_SYNC_EXT,
+               .vmode          = FB_VMODE_NONINTERLACED
+} }, {
+       .bus    = 2,
+       .addr   = 0x38,
+       .pixfmt = IPU_PIX_FMT_LVDS666,
+       .detect = detect_i2c,
+       .enable = enable_lvds,
+       .mode   = {
+               .name           = "wsvga-lvds",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 600,
+               .pixclock       = 15385,
+               .left_margin    = 220,
+               .right_margin   = 40,
+               .upper_margin   = 21,
+               .lower_margin   = 7,
+               .hsync_len      = 60,
+               .vsync_len      = 10,
+               .sync           = FB_SYNC_EXT,
+               .vmode          = FB_VMODE_NONINTERLACED
+} }, {
+       .bus    = 2,
+       .addr   = 0x48,
+       .pixfmt = IPU_PIX_FMT_RGB666,
+       .detect = detect_i2c,
+       .enable = enable_rgb,
+       .mode   = {
+               .name           = "wvga-rgb",
+               .refresh        = 57,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = 37037,
+               .left_margin    = 40,
+               .right_margin   = 60,
+               .upper_margin   = 10,
+               .lower_margin   = 10,
+               .hsync_len      = 20,
+               .vsync_len      = 10,
+               .sync           = 0,
+               .vmode          = FB_VMODE_NONINTERLACED
+} } };
+
+int board_video_skip(void)
+{
+       int i;
+       int ret;
+       char const *panel = getenv("panel");
+       if (!panel) {
+               for (i = 0; i < ARRAY_SIZE(displays); i++) {
+                       struct display_info_t const *dev = displays+i;
+                       if (dev->detect(dev)) {
+                               panel = dev->mode.name;
+                               printf("auto-detected panel %s\n", panel);
+                               break;
+                       }
+               }
+               if (!panel) {
+                       panel = displays[0].mode.name;
+                       printf("No panel detected: default to %s\n", panel);
+               }
+       } else {
+               for (i = 0; i < ARRAY_SIZE(displays); i++) {
+                       if (!strcmp(panel, displays[i].mode.name))
+                               break;
+               }
+       }
+       if (i < ARRAY_SIZE(displays)) {
+               ret = ipuv3_fb_init(&displays[i].mode, 0,
+                                   displays[i].pixfmt);
+               if (!ret) {
+                       displays[i].enable(displays+i);
+                       printf("Display: %s (%ux%u)\n",
+                              displays[i].mode.name,
+                              displays[i].mode.xres,
+                              displays[i].mode.yres);
+               } else
+                       printf("LCD %s cannot be configured: %d\n",
+                              displays[i].mode.name, ret);
+       } else {
+               printf("unsupported panel %s\n", panel);
+               ret = -EINVAL;
+       }
+       return (0 != ret);
+}
+
+static void setup_display(void)
+{
+       struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+       struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+       struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+       struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+
+       int reg;
+
+       /* Turn on LDB0,IPU,IPU DI0 clocks */
+       reg = __raw_readl(&mxc_ccm->CCGR3);
+       reg |=   MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET
+               |MXC_CCM_CCGR3_LDB_DI0_MASK;
+       writel(reg, &mxc_ccm->CCGR3);
+
+       /* Turn on HDMI PHY clock */
+       reg = __raw_readl(&mxc_ccm->CCGR2);
+       reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK
+              |MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
+       writel(reg, &mxc_ccm->CCGR2);
+
+       /* clear HDMI PHY reset */
+       writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
+
+       /* set PFD1_FRAC to 0x13 == 455 MHz (480*18)/0x13 */
+       writel(ANATOP_PFD_480_PFD1_FRAC_MASK, &anatop->pfd_480_clr);
+       writel(0x13<<ANATOP_PFD_480_PFD1_FRAC_SHIFT, &anatop->pfd_480_set);
+
+       /* set LDB0, LDB1 clk select to 011/011 */
+       reg = readl(&mxc_ccm->cs2cdr);
+       reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
+                |MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
+       reg |= (3<<MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)
+             |(3<<MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
+       writel(reg, &mxc_ccm->cs2cdr);
+
+       reg = readl(&mxc_ccm->cscmr2);
+       reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV;
+       writel(reg, &mxc_ccm->cscmr2);
+
+       reg = readl(&mxc_ccm->chsccdr);
+       reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK
+               |MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK
+               |MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
+       reg |= (CHSCCDR_CLK_SEL_LDB_DI0
+               <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
+             |(CHSCCDR_PODF_DIVIDE_BY_3
+               <<MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
+             |(CHSCCDR_IPU_PRE_CLK_540M_PFD
+               <<MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
+       writel(reg, &mxc_ccm->chsccdr);
+
+       reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
+            |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
+            |IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW
+            |IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG
+            |IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT
+            |IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG
+            |IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT
+            |IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED
+            |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
+       writel(reg, &iomux->gpr[2]);
+
+       reg = readl(&iomux->gpr[3]);
+       reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
+           | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
+              <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
+       writel(reg, &iomux->gpr[3]);
+
+       /* backlights off until needed */
+       imx_iomux_v3_setup_multiple_pads(backlight_pads,
+                                        ARRAY_SIZE(backlight_pads));
+       gpio_direction_input(LVDS_BACKLIGHT_GP);
+       gpio_direction_input(RGB_BACKLIGHT_GP);
+}
+#endif
+
+int board_early_init_f(void)
+{
+       setup_iomux_uart();
+       setup_buttons();
+
+#if defined(CONFIG_VIDEO_IPUV3)
+       setup_display();
+#endif
+       return 0;
+}
+
+/*
+ * Do not overwrite the console
+ * Use always serial for U-Boot console
+ */
+int overwrite_console(void)
+{
+       return 1;
+}
+
+int board_init(void)
+{
+       /* address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+#ifdef CONFIG_MXC_SPI
+       setup_spi();
+#endif
+       setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
+       setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
+       setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
+
+#ifdef CONFIG_CMD_SATA
+       setup_sata();
+#endif
+
+       return 0;
+}
+
+int checkboard(void)
+{
+       puts("Board: MX6Q-Sabre Lite\n");
+
+       return 0;
+}
+
+struct button_key {
+       char const      *name;
+       unsigned        gpnum;
+       char            ident;
+};
+
+static struct button_key const buttons[] = {
+       {"back",        IMX_GPIO_NR(2, 2),      'B'},
+       {"home",        IMX_GPIO_NR(2, 4),      'H'},
+       {"menu",        IMX_GPIO_NR(2, 1),      'M'},
+       {"search",      IMX_GPIO_NR(2, 3),      'S'},
+       {"volup",       IMX_GPIO_NR(7, 13),     'V'},
+       {"voldown",     IMX_GPIO_NR(4, 5),      'v'},
+};
+
+/*
+ * generate a null-terminated string containing the buttons pressed
+ * returns number of keys pressed
+ */
+static int read_keys(char *buf)
+{
+       int i, numpressed = 0;
+       for (i = 0; i < ARRAY_SIZE(buttons); i++) {
+               if (!gpio_get_value(buttons[i].gpnum))
+                       buf[numpressed++] = buttons[i].ident;
+       }
+       buf[numpressed] = '\0';
+       return numpressed;
+}
+
+static int do_kbd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       char envvalue[ARRAY_SIZE(buttons)+1];
+       int numpressed = read_keys(envvalue);
+       setenv("keybd", envvalue);
+       return numpressed == 0;
+}
+
+U_BOOT_CMD(
+       kbd, 1, 1, do_kbd,
+       "Tests for keypresses, sets 'keybd' environment variable",
+       "Returns 0 (true) to shell if key is pressed."
+);
+
+#ifdef CONFIG_PREBOOT
+static char const kbd_magic_prefix[] = "key_magic";
+static char const kbd_command_prefix[] = "key_cmd";
+
+static void preboot_keys(void)
+{
+       int numpressed;
+       char keypress[ARRAY_SIZE(buttons)+1];
+       numpressed = read_keys(keypress);
+       if (numpressed) {
+               char *kbd_magic_keys = getenv("magic_keys");
+               char *suffix;
+               /*
+                * loop over all magic keys
+                */
+               for (suffix = kbd_magic_keys; *suffix; ++suffix) {
+                       char *keys;
+                       char magic[sizeof(kbd_magic_prefix) + 1];
+                       sprintf(magic, "%s%c", kbd_magic_prefix, *suffix);
+                       keys = getenv(magic);
+                       if (keys) {
+                               if (!strcmp(keys, keypress))
+                                       break;
+                       }
+               }
+               if (*suffix) {
+                       char cmd_name[sizeof(kbd_command_prefix) + 1];
+                       char *cmd;
+                       sprintf(cmd_name, "%s%c", kbd_command_prefix, *suffix);
+                       cmd = getenv(cmd_name);
+                       if (cmd) {
+                               setenv("preboot", cmd);
+                               return;
+                       }
+               }
+       }
+}
+#endif
+
+#ifdef CONFIG_CMD_BMODE
+static const struct boot_mode board_boot_modes[] = {
+       /* 4 bit bus width */
+       {"mmc0",        MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
+       {"mmc1",        MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
+       {NULL,          0},
+};
+#endif
+
+int misc_init_r(void)
+{
+#ifdef CONFIG_PREBOOT
+       preboot_keys();
+#endif
+
+#ifdef CONFIG_CMD_BMODE
+       add_board_boot_modes(board_boot_modes);
+#endif
+       return 0;
+}
index 2f7198d3bfdfc0b438ec185973d62dcb3dc45156..215faa98fac2247cd268f471f29fabf605a3329c 100644 (file)
@@ -85,7 +85,7 @@ static iomux_v3_cfg_t const enet_pads[] = {
        MX6_PAD_RGMII_RD3__RGMII_RD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* AR8031 PHY Reset */
-       MX6_PAD_ENET_CRS_DV__GPIO1_IO25         | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_ENET_CRS_DV__GPIO1_IO25,
 };
 
 static void setup_iomux_enet(void)
@@ -109,7 +109,7 @@ static iomux_v3_cfg_t const usdhc2_pads[] = {
        MX6_PAD_NANDF_D5__SD2_DATA5     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_NANDF_D6__SD2_DATA6     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_NANDF_D7__SD2_DATA7     | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D2__GPIO2_IO02    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_D2__GPIO2_IO02, /* CD */
 };
 
 static iomux_v3_cfg_t const usdhc3_pads[] = {
@@ -123,7 +123,7 @@ static iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6_PAD_NANDF_D0__GPIO2_IO00    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+       MX6_PAD_NANDF_D0__GPIO2_IO00, /* CD */
 };
 
 static iomux_v3_cfg_t const usdhc4_pads[] = {
@@ -143,40 +143,40 @@ static iomux_v3_cfg_t const ecspi1_pads[] = {
        MX6_PAD_KEY_COL0__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX6_PAD_KEY_COL1__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
        MX6_PAD_KEY_ROW0__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
-       MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_KEY_ROW1__GPIO4_IO09,
 };
 
 static iomux_v3_cfg_t const rgb_pads[] = {
-       MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+       MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+       MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02,
+       MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03,
+       MX6_PAD_DI0_PIN4__IPU1_DI0_PIN04,
+       MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
+       MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
+       MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
+       MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
+       MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
+       MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
+       MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
+       MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
+       MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
+       MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
+       MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
+       MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
+       MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
+       MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
+       MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
+       MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
+       MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
+       MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
+       MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
+       MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
+       MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
+       MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
+       MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
+       MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
+       MX6_PAD_SD1_DAT3__GPIO1_IO21,
 };
 
 static void enable_rgb(struct display_info_t const *dev)
@@ -204,8 +204,8 @@ static void setup_spi(void)
 }
 
 iomux_v3_cfg_t const pcie_pads[] = {
-       MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),        /* POWER */
-       MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL),        /* RESET */
+       MX6_PAD_EIM_D19__GPIO3_IO19,    /* POWER */
+       MX6_PAD_GPIO_17__GPIO7_IO12,    /* RESET */
 };
 
 static void setup_pcie(void)
@@ -543,12 +543,12 @@ int board_eth_init(bd_t *bis)
 #define UCTRL_PWR_POL          (1 << 9)
 
 static iomux_v3_cfg_t const usb_otg_pads[] = {
-       MX6_PAD_EIM_D22__USB_OTG_PWR | MUX_PAD_CTRL(NO_PAD_CTRL),
-       MX6_PAD_ENET_RX_ER__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_D22__USB_OTG_PWR,
+       MX6_PAD_ENET_RX_ER__USB_OTG_ID,
 };
 
 static iomux_v3_cfg_t const usb_hc1_pads[] = {
-       MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_ENET_TXD1__GPIO1_IO29,
 };
 
 static void setup_usb(void)
diff --git a/board/freescale/titanium/titanium.c b/board/freescale/titanium/titanium.c
new file mode 100644 (file)
index 0000000..82e7f98
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2013 Stefan Roese <sr@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/mx6q_pins.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/mxc_i2c.h>
+#include <asm/imx-common/boot_mode.h>
+#include <mmc.h>
+#include <fsl_esdhc.h>
+#include <micrel.h>
+#include <miiphy.h>
+#include <netdev.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |      \
+                       PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |      \
+                       PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define ENET_PAD_CTRL  (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED          |     \
+                       PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+
+#define I2C_PAD_CTRL   (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |      \
+                        PAD_CTL_DSE_40ohm | PAD_CTL_HYS |              \
+                        PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+
+int dram_init(void)
+{
+       gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
+
+       return 0;
+}
+
+iomux_v3_cfg_t const uart1_pads[] = {
+       MX6_PAD_SD3_DAT6__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+       MX6_PAD_SD3_DAT7__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+iomux_v3_cfg_t const uart2_pads[] = {
+       MX6_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+       MX6_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+iomux_v3_cfg_t const uart4_pads[] = {
+       MX6_PAD_CSI0_DAT12__UART4_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+       MX6_PAD_CSI0_DAT13__UART4_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
+
+struct i2c_pads_info i2c_pad_info0 = {
+       .scl = {
+               .i2c_mode  = MX6_PAD_CSI0_DAT9__I2C1_SCL | PC,
+               .gpio_mode = MX6_PAD_CSI0_DAT9__GPIO_5_27 | PC,
+               .gp = IMX_GPIO_NR(5, 27)
+       },
+       .sda = {
+                .i2c_mode = MX6_PAD_CSI0_DAT8__I2C1_SDA | PC,
+                .gpio_mode = MX6_PAD_CSI0_DAT8__GPIO_5_26 | PC,
+                .gp = IMX_GPIO_NR(5, 26)
+        }
+};
+
+struct i2c_pads_info i2c_pad_info2 = {
+       .scl = {
+               .i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC,
+               .gpio_mode = MX6_PAD_GPIO_3__GPIO_1_3 | PC,
+               .gp = IMX_GPIO_NR(1, 3)
+       },
+       .sda = {
+                .i2c_mode = MX6_PAD_GPIO_16__I2C3_SDA | PC,
+                .gpio_mode = MX6_PAD_GPIO_16__GPIO_7_11 | PC,
+                .gp = IMX_GPIO_NR(7, 11)
+        }
+};
+
+iomux_v3_cfg_t const usdhc3_pads[] = {
+       MX6_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+       MX6_PAD_SD3_DAT5__GPIO_7_0, /* CD */
+};
+
+iomux_v3_cfg_t const enet_pads1[] = {
+       MX6_PAD_ENET_MDIO__ENET_MDIO            | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_ENET_MDC__ENET_MDC              | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TXC__ENET_RGMII_TXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD0__ENET_RGMII_TD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD1__ENET_RGMII_TD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD2__ENET_RGMII_TD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TD3__ENET_RGMII_TD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_ENET_REF_CLK__ENET_TX_CLK       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       /* pin 35 - 1 (PHY_AD2) on reset */
+       MX6_PAD_RGMII_RXC__GPIO_6_30,
+       /* pin 32 - 1 - (MODE0) all */
+       MX6_PAD_RGMII_RD0__GPIO_6_25,
+       /* pin 31 - 1 - (MODE1) all */
+       MX6_PAD_RGMII_RD1__GPIO_6_27,
+       /* pin 28 - 1 - (MODE2) all */
+       MX6_PAD_RGMII_RD2__GPIO_6_28,
+       /* pin 27 - 1 - (MODE3) all */
+       MX6_PAD_RGMII_RD3__GPIO_6_29,
+       /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
+       MX6_PAD_RGMII_RX_CTL__GPIO_6_24,
+       /* pin 42 PHY nRST */
+       MX6_PAD_EIM_D23__GPIO_3_23,
+};
+
+iomux_v3_cfg_t const enet_pads2[] = {
+       MX6_PAD_RGMII_RXC__ENET_RGMII_RXC       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD0__ENET_RGMII_RD0       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD1__ENET_RGMII_RD1       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD2__ENET_RGMII_RD2       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RD3__ENET_RGMII_RD3       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+       MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
+};
+
+iomux_v3_cfg_t nfc_pads[] = {
+       MX6_PAD_NANDF_CLE__RAWNAND_CLE,
+       MX6_PAD_NANDF_ALE__RAWNAND_ALE,
+       MX6_PAD_NANDF_WP_B__RAWNAND_RESETN,
+       MX6_PAD_NANDF_RB0__RAWNAND_READY0,
+       MX6_PAD_NANDF_CS0__RAWNAND_CE0N,
+       MX6_PAD_NANDF_CS1__RAWNAND_CE1N,
+       MX6_PAD_NANDF_CS2__RAWNAND_CE2N,
+       MX6_PAD_NANDF_CS3__RAWNAND_CE3N,
+       MX6_PAD_SD4_CMD__RAWNAND_RDN,
+       MX6_PAD_SD4_CLK__RAWNAND_WRN,
+       MX6_PAD_NANDF_D0__RAWNAND_D0,
+       MX6_PAD_NANDF_D1__RAWNAND_D1,
+       MX6_PAD_NANDF_D2__RAWNAND_D2,
+       MX6_PAD_NANDF_D3__RAWNAND_D3,
+       MX6_PAD_NANDF_D4__RAWNAND_D4,
+       MX6_PAD_NANDF_D5__RAWNAND_D5,
+       MX6_PAD_NANDF_D6__RAWNAND_D6,
+       MX6_PAD_NANDF_D7__RAWNAND_D7,
+       MX6_PAD_SD4_DAT0__RAWNAND_DQS,
+};
+
+static void setup_gpmi_nand(void)
+{
+       struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+       /* config gpmi nand iomux */
+       imx_iomux_v3_setup_multiple_pads(nfc_pads,
+                                        ARRAY_SIZE(nfc_pads));
+
+       /* config gpmi and bch clock to 100 MHz */
+       clrsetbits_le32(&mxc_ccm->cs2cdr,
+                       MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
+                       MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
+                       MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
+                       MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
+                       MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
+                       MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
+
+       /* enable gpmi and bch clock gating */
+       setbits_le32(&mxc_ccm->CCGR4,
+                    MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
+                    MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
+                    MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
+                    MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
+                    MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
+
+       /* enable apbh clock gating */
+       setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
+}
+
+static void setup_iomux_enet(void)
+{
+       gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
+       gpio_direction_output(IMX_GPIO_NR(6, 30), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 25), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
+       gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
+       imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
+       gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
+
+       /* Need delay 10ms according to KSZ9021 spec */
+       udelay(1000 * 10);
+       gpio_set_value(IMX_GPIO_NR(3, 23), 1);
+
+       imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
+}
+
+static void setup_iomux_uart(void)
+{
+       imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
+       imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
+       imx_iomux_v3_setup_multiple_pads(uart4_pads, ARRAY_SIZE(uart4_pads));
+}
+
+#ifdef CONFIG_USB_EHCI_MX6
+int board_ehci_hcd_init(int port)
+{
+       return 0;
+}
+
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+struct fsl_esdhc_cfg usdhc_cfg[1] = {
+       { USDHC3_BASE_ADDR },
+};
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+
+       if (cfg->esdhc_base == USDHC3_BASE_ADDR) {
+               gpio_direction_input(IMX_GPIO_NR(7, 0));
+               return !gpio_get_value(IMX_GPIO_NR(7, 0));
+       }
+
+       return 0;
+}
+
+int board_mmc_init(bd_t *bis)
+{
+       /*
+        * Only one USDHC controller on titianium
+        */
+       imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+       usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+
+       return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+}
+#endif
+
+int board_phy_config(struct phy_device *phydev)
+{
+       /* min rx data delay */
+       ksz9021_phy_extended_write(phydev,
+                                  MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
+       /* min tx data delay */
+       ksz9021_phy_extended_write(phydev,
+                                  MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
+       /* max rx/tx clock delay, min rx/tx control */
+       ksz9021_phy_extended_write(phydev,
+                                  MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
+       if (phydev->drv->config)
+               phydev->drv->config(phydev);
+
+       return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       setup_iomux_enet();
+
+       ret = cpu_eth_init(bis);
+       if (ret)
+               printf("FEC MXC: %s:failed\n", __func__);
+
+       return 0;
+}
+
+int board_early_init_f(void)
+{
+       setup_iomux_uart();
+
+       return 0;
+}
+
+int board_init(void)
+{
+       /* address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+       setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
+       setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
+
+       setup_gpmi_nand();
+
+       return 0;
+}
+
+int checkboard(void)
+{
+       puts("Board: Titanium\n");
+
+       return 0;
+}
+
+#ifdef CONFIG_CMD_BMODE
+static const struct boot_mode board_boot_modes[] = {
+       /* NAND */
+       { "nand", MAKE_CFGVAL(0x80, 0x02, 0x00, 0x00) },
+       /* 4 bit bus width */
+       { "mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00) },
+       { "mmc1", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00) },
+       { NULL, 0 },
+};
+#endif
+
+int misc_init_r(void)
+{
+#ifdef CONFIG_CMD_BMODE
+       add_board_boot_modes(board_boot_modes);
+#endif
+
+       return 0;
+}
diff --git a/board/karo/common/Makefile b/board/karo/common/Makefile
new file mode 100644 (file)
index 0000000..05c1d34
--- /dev/null
@@ -0,0 +1,13 @@
+#
+# (C) Copyright 2012-2015 Lothar Waßmann <LW@KARO-electronics.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+ifeq ($(CONFIG_SPL_BUILD),)
+       obj-$(CONFIG_OF_LIBFDT)         += fdt.o
+       obj-$(CONFIG_SPLASH_SCREEN)     += splashimage.o
+endif
+obj-$(CONFIG_CMD_NAND)                 += nand.o
+obj-$(CONFIG_ENV_IS_IN_MMC)            += mmc.o
+obj-y                                  += env.o
diff --git a/board/karo/common/env.c b/board/karo/common/env.c
new file mode 100644 (file)
index 0000000..7dbb7c8
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+
+#include "karo.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const char const *cleanup_vars[] = {
+       "bootargs",
+       "fileaddr",
+       "filesize",
+       "safeboot",
+       "wdreset",
+};
+
+void env_cleanup(void)
+{
+       size_t i;
+
+       for (i = 0; i < ARRAY_SIZE(cleanup_vars); i++) {
+               setenv(cleanup_vars[i], NULL);
+       }
+}
diff --git a/board/karo/common/fdt.c b/board/karo/common/fdt.c
new file mode 100644 (file)
index 0000000..c6f4dcc
--- /dev/null
@@ -0,0 +1,856 @@
+/*
+ * (C) Copyright 2012-2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#include <common.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <nand.h>
+#include <mxcfb.h>
+#include <linux/list.h>
+#include <linux/fb.h>
+#include <jffs2/load_kernel.h>
+#include <malloc.h>
+
+#include "karo.h"
+
+#ifdef CONFIG_MAX_DTB_SIZE
+#define MAX_DTB_SIZE   CONFIG_MAX_DTB_SIZE
+#else
+#define MAX_DTB_SIZE   SZ_64K
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void karo_set_fdtsize(void *fdt)
+{
+       size_t fdtsize = getenv_ulong("fdtsize", 16, 0);
+
+       if (fdtsize == fdt_totalsize(fdt)) {
+               return;
+       }
+       debug("FDT size changed from %u to %u\n",
+               fdtsize, fdt_totalsize(fdt));
+       setenv_hex("fdtsize", fdt_totalsize(fdt));
+}
+
+static void *karo_fdt_load_dtb(void)
+{
+       int ret;
+       void *fdt;
+
+       if (getenv("fdtaddr") == NULL)
+               setenv_hex("fdtaddr", CONFIG_SYS_FDT_ADDR);
+       fdt = (void *)getenv_ulong("fdtaddr", 16, CONFIG_SYS_FDT_ADDR);
+
+       if (had_ctrlc()) {
+               printf("aborting DTB load\n");
+               return NULL;
+       }
+
+       /* clear FDT header in memory */
+       memset(fdt, 0, 4);
+
+       ret = karo_load_part("dtb", fdt, MAX_DTB_SIZE);
+       if (ret) {
+               printf("Failed to load dtb from flash: %d\n", ret);
+               return NULL;
+       }
+
+       if (fdt_check_header(fdt)) {
+               debug("No valid DTB in flash\n");
+               return NULL;
+       }
+       debug("Using DTB from flash\n");
+       karo_set_fdtsize(fdt);
+       return fdt;
+}
+
+void karo_fdt_move_fdt(void)
+{
+       void *fdt;
+       unsigned long fdt_addr = getenv_ulong("fdtaddr", 16, 0);
+
+       if (working_fdt) {
+               debug("DTB already loaded\n");
+               return;
+       }
+
+       setenv("fdtsize", 0);
+
+       if (!fdt_addr) {
+               fdt_addr = CONFIG_SYS_FDT_ADDR;
+               printf("fdtaddr is not set; using default: %08lx\n",
+                       fdt_addr);
+       }
+
+       fdt = karo_fdt_load_dtb();
+       if (fdt == NULL) {
+               fdt = (void *)gd->fdt_blob;
+               if (fdt == NULL) {
+#ifdef CONFIG_OF_EMBED
+                       printf("Compiled in FDT not found");
+#else
+                       printf("No FDT found");
+#endif
+                       printf("; creating empty DTB\n");
+                       fdt = (void *)fdt_addr;
+                       fdt_create_empty_tree(fdt, 256);
+               } else {
+                       printf("No DTB in flash; using default DTB\n");
+               }
+               debug("Checking FDT header @ %p\n", fdt);
+               if (fdt_check_header(fdt)) {
+                       printf("ERROR: No valid DTB found at %p\n", fdt);
+                       return;
+               }
+               debug("Moving FDT from %p..%p to %08lx..%08lx\n",
+                       fdt, fdt + fdt_totalsize(fdt) - 1,
+                       fdt_addr, fdt_addr + fdt_totalsize(fdt) - 1);
+               memmove((void *)fdt_addr, fdt, fdt_totalsize(fdt));
+       }
+       set_working_fdt_addr((void *)fdt_addr);
+       gd->fdt_blob = fdt;
+       karo_set_fdtsize(fdt);
+}
+
+void karo_fdt_remove_node(void *blob, const char *node)
+{
+       int off = fdt_path_offset(blob, node);
+       int ret;
+
+       debug("Removing node '%s' from DT\n", node);
+
+       if (off < 0) {
+               printf("Could not find node '%s': %s\n", node,
+                       fdt_strerror(off));
+       } else {
+               ret = fdt_del_node(blob, off);
+               if (ret)
+                       printf("Failed to remove node '%s': %s\n",
+                               node, fdt_strerror(ret));
+       }
+       karo_set_fdtsize(blob);
+}
+
+void karo_fdt_enable_node(void *blob, const char *node, int enable)
+{
+       int off = fdt_path_offset(blob, node);
+
+       debug("%sabling node '%s'\n", enable ? "En" : "Dis", node);
+       if (off < 0) {
+               printf("Could not find node '%s': %s\n", node,
+                       fdt_strerror(off));
+               return;
+       }
+       fdt_set_node_status(blob, off,
+                       enable ? FDT_STATUS_OKAY : FDT_STATUS_DISABLED, 0);
+
+       karo_set_fdtsize(blob);
+}
+
+static void fdt_disable_tp_node(void *blob, const char *name)
+{
+       int offs = fdt_node_offset_by_compatible(blob, -1, name);
+
+       while (offs >= 0) {
+               debug("Disabling node '%s'\n", name);
+               fdt_set_node_status(blob, offs, FDT_STATUS_DISABLED, 0);
+               offs = fdt_node_offset_by_compatible(blob, offs, name);
+       }
+}
+
+void karo_fdt_fixup_touchpanel(void *blob, const char *panels[],
+                       size_t num_panels)
+{
+       int i;
+       const char *model = getenv("touchpanel");
+
+       for (i = 0; i < num_panels; i++) {
+               const char *tp = panels[i];
+
+               if (model != NULL) {
+                       if (strcmp(model, tp) == 0)
+                               continue;
+                       while (tp != NULL) {
+                               if (*tp != '\0' && strcmp(model, tp + 1) == 0)
+                                       break;
+                               tp = strpbrk(tp + 1, ",-");
+                       }
+                       if (tp != NULL)
+                               continue;
+               }
+               fdt_disable_tp_node(blob, panels[i]);
+       }
+       karo_set_fdtsize(blob);
+}
+
+static int karo_fdt_disable_node_phandle(void *blob, const char *parent,
+                                       const char *name)
+{
+       const uint32_t *ph;
+       int off;
+
+       off = fdt_path_offset(blob, parent);
+       if (off < 0) {
+               printf("Failed to find node '%s'\n", parent);
+               return off;
+       }
+
+       ph = fdt_getprop(blob, off, name, NULL);
+       if (ph == NULL) {
+               debug("Failed to find '%s' phandle in node '%s'\n", name,
+                       fdt_get_name(blob, off, NULL));
+               return -FDT_ERR_NOTFOUND;
+       }
+
+       off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*ph));
+       if (off <= 0) {
+               printf("Failed to find '%s' node via phandle %04x\n",
+                       name, fdt32_to_cpu(*ph));
+               return -FDT_ERR_NOTFOUND;
+       }
+       return fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
+}
+
+void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy,
+                       const char *phy_supply)
+{
+       const char *otg_mode = getenv("otg_mode");
+       int off;
+       int ret;
+       int disable_otg = 0;
+       int disable_phy_pins = 0;
+
+       debug("OTG mode is '%s'\n", otg_mode ? otg_mode : "<UNSET>");
+
+       off = fdt_path_offset(blob, node);
+       if (off < 0) {
+               debug("Failed to find node %s\n", node);
+               return;
+       }
+
+       if (otg_mode && (strcasecmp(otg_mode, "device") == 0 ||
+                               strcasecmp(otg_mode, "gadget") == 0)) {
+               debug("Setting dr_mode to 'peripheral'\n");
+               ret = fdt_setprop_string(blob, off, "dr_mode", "peripheral");
+               disable_phy_pins = 1;
+       } else if (otg_mode && strcasecmp(otg_mode, "host") == 0) {
+               debug("Setting dr_mode to 'host'\n");
+               ret = fdt_setprop_string(blob, off, "dr_mode", "host");
+       } else if (otg_mode && strcasecmp(otg_mode, "otg") == 0) {
+               debug("Setting dr_mode to 'otg'\n");
+               ret = fdt_setprop_string(blob, off, "dr_mode", "otg");
+       } else {
+               if (otg_mode && strcasecmp(otg_mode, "none") != 0)
+                       printf("Invalid 'otg_mode' setting '%s'; disabling usbotg port\n",
+                               otg_mode);
+               disable_otg = 1;
+               ret = 0;
+       }
+
+       if ((!disable_phy_pins && !disable_otg) || ret)
+               goto out;
+
+       ret = karo_fdt_disable_node_phandle(blob, node, phy_supply);
+       if (ret && ret == -FDT_ERR_NOTFOUND) {
+               const uint32_t *ph;
+
+               ph = fdt_getprop(blob, off, phy, NULL);
+               if (ph == NULL) {
+                       printf("Failed to find '%s' phandle in node '%s'\n",
+                               phy, node);
+                       ret = -FDT_ERR_NOTFOUND;
+                       goto out;
+               }
+               off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*ph));
+               if (off < 0) {
+                       printf("Failed to find '%s' node via phandle %04x\n",
+                               phy, fdt32_to_cpu(*ph));
+                       ret = off;
+                       goto out;
+               }
+               ph = fdt_getprop(blob, off, phy_supply, NULL);
+               if (ph == NULL) {
+                       debug("Failed to find '%s' phandle in node '%s'\n",
+                               phy_supply, fdt_get_name(blob, off, NULL));
+                       ret = -FDT_ERR_NOTFOUND;
+                       goto disable_otg;
+               }
+               ret = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*ph));
+               if (ret > 0) {
+                       debug("Disabling node %s via phandle %s:%s\n",
+                               fdt_get_name(blob, ret, NULL),
+                               fdt_get_name(blob, off, NULL), phy_supply);
+                       ret = fdt_set_node_status(blob, ret,
+                                               FDT_STATUS_DISABLED, 0);
+               }
+       }
+       if (ret && ret != -FDT_ERR_NOTFOUND)
+               goto out;
+
+disable_otg:
+       if (disable_otg) {
+               debug("Disabling '%s'\n", fdt_get_name(blob, off, NULL));
+               ret = fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
+               if (ret > 0)
+                       ret = karo_fdt_disable_node_phandle(blob, node, phy);
+       } else if (disable_phy_pins) {
+               debug("Removing '%s' from node '%s'\n", phy_supply,
+                       fdt_get_name(blob, off, NULL));
+               ret = fdt_delprop(blob, off, phy_supply);
+       }
+
+out:
+       if (ret && ret != -FDT_ERR_NOTFOUND)
+               printf("Failed to update usbotg: %s\n", fdt_strerror(ret));
+       else
+               debug("node '%s' updated\n", node);
+       karo_set_fdtsize(blob);
+}
+
+static inline int karo_fdt_flexcan_enabled(void *blob)
+{
+       static const char *can_ifs[] = {
+               "can0",
+               "can1",
+       };
+       size_t i;
+
+       for (i = 0; i < ARRAY_SIZE(can_ifs); i++) {
+               const char *status;
+               int off = fdt_path_offset(blob, can_ifs[i]);
+
+               if (off < 0) {
+                       debug("node '%s' not found\n", can_ifs[i]);
+                       continue;
+               }
+               status = fdt_getprop(blob, off, "status", NULL);
+               if (status && strcmp(status, "okay") == 0) {
+                       debug("%s is enabled\n", can_ifs[i]);
+                       return 1;
+               }
+       }
+       debug("can driver is disabled\n");
+       return 0;
+}
+
+static inline void karo_fdt_set_lcd_pins(void *blob, const char *name)
+{
+       int off = fdt_path_offset(blob, name);
+       u32 ph;
+       const struct fdt_property *pc;
+       int len;
+
+       if (off < 0)
+               return;
+
+       ph = fdt_create_phandle(blob, off);
+       if (!ph)
+               return;
+
+       off = fdt_path_offset(blob, "display");
+       if (off < 0)
+               return;
+
+       pc = fdt_get_property(blob, off, "pinctrl-0", &len);
+       if (!pc || len < sizeof(ph))
+               return;
+
+       memcpy((void *)pc->data, &ph, sizeof(ph));
+       fdt_setprop_cell(blob, off, "pinctrl-0", ph);
+}
+
+void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
+{
+       int ret;
+       const char *xcvr_status = "disabled";
+       const char *otg_mode = getenv("otg_mode");
+
+       if (xcvr_present) {
+               if (karo_fdt_flexcan_enabled(blob)) {
+                       if (!is_lvds()) {
+                               debug("Changing LCD to use 23bits only\n");
+                               karo_fdt_set_lcd_pins(blob, "lcdif_23bit_pins_a");
+                               xcvr_status = NULL;
+                       }
+               } else if (!is_lvds()) {
+                       debug("Changing LCD to use 24bits\n");
+                       karo_fdt_set_lcd_pins(blob, "lcdif_24bit_pins_a");
+               }
+       } else {
+               int off = fdt_path_offset(blob, "can0");
+
+               if (off >= 0)
+                       fdt_delprop(blob, off, "xceiver-supply");
+               off = fdt_path_offset(blob, "can1");
+               if (off >= 0)
+                       fdt_delprop(blob, off, "xceiver-supply");
+               if (!is_lvds())
+                       karo_fdt_set_lcd_pins(blob, "lcdif_24bit_pins_a");
+       }
+
+       if (otg_mode && strcasecmp(otg_mode, "host") == 0)
+               karo_fdt_enable_node(blob, "can1", 0);
+
+       if (xcvr_status) {
+               debug("Disabling CAN XCVR\n");
+               ret = fdt_find_and_setprop(blob, "reg_can_xcvr", "status",
+                                       xcvr_status, strlen(xcvr_status) + 1, 1);
+               if (ret)
+                       printf("Failed to disable CAN transceiver switch: %s\n",
+                               fdt_strerror(ret));
+       }
+}
+
+void karo_fdt_del_prop(void *blob, const char *compat, u32 offs,
+                       const char *propname)
+{
+       int offset = -1;
+       const fdt32_t *reg = NULL;
+
+       while (1) {
+               offset = fdt_node_offset_by_compatible(blob, offset, compat);
+               if (offset <= 0)
+                       return;
+
+               reg = fdt_getprop(blob, offset, "reg", NULL);
+               if (reg == NULL)
+                       return;
+
+               if (fdt32_to_cpu(*reg) == offs)
+                       break;
+       }
+       debug("Removing property '%s' from node %s@%x\n",
+               propname, compat, offs);
+       fdt_delprop(blob, offset, propname);
+
+       karo_set_fdtsize(blob);
+}
+
+static int fdt_init_fb_mode(const void *blob, int off, struct fb_videomode *fb_mode)
+{
+       const uint32_t *prop;
+
+       memset(fb_mode, 0, sizeof(*fb_mode));
+
+       prop = fdt_getprop(blob, off, "clock-frequency", NULL);
+       if (prop)
+               fb_mode->pixclock = KHZ2PICOS(fdt32_to_cpu(*prop) / 1000);
+
+       prop = fdt_getprop(blob, off, "hactive", NULL);
+       if (prop)
+               fb_mode->xres = fdt32_to_cpu(*prop);
+
+       prop = fdt_getprop(blob, off, "vactive", NULL);
+       if (prop)
+               fb_mode->yres = fdt32_to_cpu(*prop);
+
+       prop = fdt_getprop(blob, off, "hback-porch", NULL);
+       if (prop)
+               fb_mode->left_margin = fdt32_to_cpu(*prop);
+
+       prop = fdt_getprop(blob, off, "hsync-len", NULL);
+       if (prop)
+               fb_mode->hsync_len = fdt32_to_cpu(*prop);
+
+       prop = fdt_getprop(blob, off, "hfront-porch", NULL);
+       if (prop)
+               fb_mode->right_margin = fdt32_to_cpu(*prop);
+
+       prop = fdt_getprop(blob, off, "vback-porch", NULL);
+       if (prop)
+               fb_mode->upper_margin = fdt32_to_cpu(*prop);
+
+       prop = fdt_getprop(blob, off, "vsync-len", NULL);
+       if (prop)
+               fb_mode->vsync_len = fdt32_to_cpu(*prop);
+
+       prop = fdt_getprop(blob, off, "vfront-porch", NULL);
+       if (prop)
+               fb_mode->lower_margin = fdt32_to_cpu(*prop);
+
+       prop = fdt_getprop(blob, off, "hsync-active", NULL);
+       if (prop)
+               fb_mode->sync |= *prop ? FB_SYNC_VERT_HIGH_ACT : 0;
+
+       prop = fdt_getprop(blob, off, "vsync-active", NULL);
+       if (prop)
+               fb_mode->sync |= *prop ? FB_SYNC_VERT_HIGH_ACT : 0;
+
+       prop = fdt_getprop(blob, off, "de-active", NULL);
+       if (prop)
+               fb_mode->sync |= *prop ? 0 : FB_SYNC_OE_LOW_ACT;
+
+       prop = fdt_getprop(blob, off, "pixelclk-active", NULL);
+       if (prop)
+               fb_mode->sync |= *prop ? 0 : FB_SYNC_CLK_LAT_FALL;
+
+       return 0;
+}
+
+static int fdt_update_native_fb_mode(void *blob, int off)
+{
+       int ret;
+       uint32_t ph;
+
+       ret = fdt_increase_size(blob, 64);
+       if (ret) {
+               printf("Warning: Failed to increase FDT size: %s\n",
+                       fdt_strerror(ret));
+       }
+       debug("Creating phandle at offset %d\n", off);
+       ph = fdt_create_phandle(blob, off);
+       if (!ph) {
+               printf("Failed to create phandle for video timing\n");
+               return -ENOMEM;
+       }
+
+       debug("phandle of %s @ %06x=%04x\n", fdt_get_name(blob, off, NULL),
+               off, ph);
+       off = fdt_parent_offset(blob, off);
+       if (off < 0)
+               return off;
+       debug("parent offset=%06x\n", off);
+       ret = fdt_setprop_cell(blob, off, "native-mode", ph);
+       if (ret)
+               printf("Failed to set property 'native-mode': %s\n",
+                       fdt_strerror(ret));
+       karo_set_fdtsize(blob);
+       return ret;
+}
+
+static int karo_fdt_find_video_timings(void *blob)
+{
+       int off = fdt_path_offset(blob, "display");
+       const char *subnode = "display-timings";
+
+       if (off < 0) {
+               debug("Could not find node 'display' in FDT: %s\n",
+                       fdt_strerror(off));
+               return off;
+       }
+
+       off = fdt_subnode_offset(blob, off, subnode);
+       if (off < 0) {
+               debug("Could not find node '%s' in FDT: %s\n", subnode,
+                       fdt_strerror(off));
+       }
+       return off;
+}
+
+int karo_fdt_get_fb_mode(void *blob, const char *name, struct fb_videomode *fb_mode)
+{
+       int off = karo_fdt_find_video_timings(blob);
+
+       if (off < 0)
+               return off;
+       while (off > 0) {
+               const char *n, *endp;
+               int len, d = 1;
+
+               off = fdt_next_node(blob, off, &d);
+               if (off < 0)
+                       return off;
+               if (d < 1)
+                       return -EINVAL;
+               if (d > 2) {
+                       debug("Skipping node @ %04x %s depth %d\n", off,
+                               fdt_get_name(blob, off, NULL), d);
+                       continue;
+               }
+
+               n = fdt_getprop(blob, off, "panel-name", &len);
+               if (!n) {
+                       n = fdt_get_name(blob, off, NULL);
+                       if (strcasecmp(n, name) == 0) {
+                               break;
+                       }
+               } else {
+                       int found = 0;
+
+                       for (endp = n + len; n < endp; n += strlen(n) + 1) {
+                               debug("Checking panel-name '%s'\n", n);
+                               if (strcasecmp(n, name) == 0) {
+                                       debug("Using node %s @ %04x\n",
+                                               fdt_get_name(blob, off, NULL), off);
+                                       found = 1;
+                                       break;
+                               }
+                       }
+                       if (found)
+                               break;
+               }
+       }
+       if (off > 0) {
+               return fdt_init_fb_mode(blob, off, fb_mode);
+       }
+       return -EINVAL;
+}
+
+#define SET_FB_PROP(n, v) ({                                           \
+       int ret;                                                        \
+       ret = fdt_setprop_u32(blob, off, n, v);                         \
+       if (ret) {                                                      \
+               printf("Failed to set property %s: %s\n", name,         \
+                       fdt_strerror(ret));                             \
+       }                                                               \
+       ret;                                                            \
+})
+
+
+int karo_fdt_create_fb_mode(void *blob, const char *name,
+                       struct fb_videomode *fb_mode)
+{
+       int off = fdt_path_offset(blob, "display");
+       int ret;
+       const char *subnode = "display-timings";
+
+       if (off < 0) {
+               printf("'display' node not found in FDT\n");
+               return off;
+       }
+
+       ret = fdt_increase_size(blob, 512);
+       if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
+               return ret;
+       }
+
+       ret = fdt_subnode_offset(blob, off, subnode);
+       if (ret < 0) {
+               debug("Could not find node '%s' in FDT: %s\n", subnode,
+                       fdt_strerror(ret));
+               ret = fdt_add_subnode(blob, off, subnode);
+               if (ret < 0) {
+                       printf("Failed to add %s subnode: %s\n", subnode,
+                               fdt_strerror(ret));
+                       return ret;
+               }
+       }
+
+       ret = fdt_add_subnode(blob, ret, name);
+       if (ret < 0) {
+               printf("Failed to add %s subnode: %s\n", name,
+                       fdt_strerror(ret));
+               return ret;
+       }
+       off = ret;
+
+       ret = SET_FB_PROP("clock-frequency",
+                       PICOS2KHZ(fb_mode->pixclock) * 1000);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("hactive", fb_mode->xres);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("vactive", fb_mode->yres);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("hback-porch", fb_mode->left_margin);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("hsync-len", fb_mode->hsync_len);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("hfront-porch", fb_mode->right_margin);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("vback-porch", fb_mode->upper_margin);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("vsync-len", fb_mode->vsync_len);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("vfront-porch", fb_mode->lower_margin);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("hsync-active",
+                       fb_mode->sync & FB_SYNC_VERT_HIGH_ACT ? 1 : 0);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("vsync-active",
+                       fb_mode->sync & FB_SYNC_VERT_HIGH_ACT ? 1 : 0);
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("de-active",
+                       !(fb_mode->sync & FB_SYNC_OE_LOW_ACT));
+       if (ret)
+               goto out;
+       ret = SET_FB_PROP("pixelclk-active",
+                       !(fb_mode->sync & FB_SYNC_CLK_LAT_FALL));
+out:
+       karo_set_fdtsize(blob);
+       return ret;
+}
+
+int karo_fdt_update_fb_mode(void *blob, const char *name)
+{
+       int off = fdt_path_offset(blob, "display");
+       const char *subnode = "display-timings";
+
+       if (off < 0)
+               return off;
+
+       if (name == NULL) {
+               int ret;
+
+               debug("Disabling node '%s' at %03x\n",
+                       fdt_get_name(blob, off, NULL), off);
+               ret = fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
+               return ret;
+       }
+
+       off = fdt_subnode_offset(blob, off, subnode);
+       if (off < 0) {
+               debug("Could not find node '%s' in FDT: %s\n", subnode,
+                       fdt_strerror(off));
+               return off;
+       }
+       while (off > 0) {
+               const char *n, *endp;
+               int len, d = 1;
+
+               off = fdt_next_node(blob, off, &d);
+               if (off < 0)
+                       return off;
+               if (d < 1)
+                       return -EINVAL;
+               if (d > 2) {
+                       debug("Skipping node @ %04x %s depth %d\n", off,
+                               fdt_get_name(blob, off, NULL), d);
+                       continue;
+               }
+
+               n = fdt_getprop(blob, off, "panel-name", &len);
+               if (!n) {
+                       n = fdt_get_name(blob, off, NULL);
+                       if (strcasecmp(n, name) == 0) {
+                               break;
+                       }
+               } else {
+                       int found = 0;
+
+                       for (endp = n + len; n < endp; n += strlen(n) + 1) {
+                               debug("Checking panel-name '%s'\n", n);
+                               if (strcasecmp(n, name) == 0) {
+                                       debug("Using node %s @ %04x\n",
+                                               fdt_get_name(blob, off, NULL), off);
+                                       found = 1;
+                                       break;
+                               }
+                       }
+                       if (found)
+                               break;
+               }
+       }
+       if (off > 0)
+               return fdt_update_native_fb_mode(blob, off);
+       return off;
+}
+
+#ifdef CONFIG_SYS_LVDS_IF
+int karo_fdt_get_lcd_bus_width(const void *blob, int default_width)
+{
+       int off = fdt_path_offset(blob, "display");
+
+       if (off >= 0) {
+               const uint32_t *prop;
+
+               prop = fdt_getprop(blob, off, "fsl,data-width", NULL);
+               if (prop)
+                       return fdt32_to_cpu(*prop);
+       }
+       return default_width;
+}
+
+int karo_fdt_get_lvds_mapping(const void *blob, int default_mapping)
+{
+       int off = fdt_path_offset(blob, "display");
+
+       if (off >= 0) {
+               const char *prop;
+
+               prop = fdt_getprop(blob, off, "fsl,data-mapping", NULL);
+               if (prop)
+                       return strcmp(prop, "jeida") == 0;
+       }
+       return default_mapping;
+}
+
+u8 karo_fdt_get_lvds_channels(const void *blob)
+{
+       static const char *lvds_chans[] = {
+               "lvds0",
+               "lvds1",
+       };
+       u8 lvds_chan_mask = 0;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(lvds_chans); i++) {
+               const char *status;
+               int off = fdt_path_offset(blob, lvds_chans[i]);
+
+               if (off < 0)
+                       continue;
+
+               status = fdt_getprop(blob, off, "status", NULL);
+               if (status && strcmp(status, "okay") == 0) {
+                       debug("%s is enabled\n", lvds_chans[i]);
+                       lvds_chan_mask |= 1 << i;
+               }
+       }
+       return lvds_chan_mask;
+}
+#endif
+
+int karo_fdt_get_backlight_polarity(const void *blob)
+{
+#ifdef CONFIG_SYS_LVDS_IF
+       const char *backlight_node = "/backlight0";
+#else
+       const char *backlight_node = "/backlight";
+#endif
+       int off = fdt_path_offset(blob, "backlight"); /* first try alias */
+       const struct fdt_property *prop;
+       int len;
+
+       if (off < 0) {
+               /*
+                * if no 'backlight' alias exists try finding '/backlight0'
+                * or '/backlight' depending on LVDS or not
+                */
+               off = fdt_path_offset(blob, backlight_node);
+               if (off < 0) {
+                       printf("%s node not found in DT\n", backlight_node);
+                       return off;
+               }
+       }
+
+       prop = fdt_get_property(blob, off, "pwms", &len);
+       if (!prop)
+               printf("'pwms' property not found\n");
+       else
+               debug("'pwms' property has len %d\n", len);
+
+       len /= sizeof(u32);
+       if (prop && len > 3) {
+               const u32 *data = (const u32 *)prop->data;
+               return fdt32_to_cpu(data[3]) == 0;
+       }
+       return 0;
+}
diff --git a/board/karo/common/karo.h b/board/karo/common/karo.h
new file mode 100644 (file)
index 0000000..aff9f37
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * (C) Copyright 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+*/
+struct fb_videomode;
+
+#ifdef CONFIG_SYS_LVDS_IF
+#define is_lvds()                      1
+#else
+#define is_lvds()                      0
+#endif
+
+void env_cleanup(void);
+
+#ifdef CONFIG_OF_LIBFDT
+void karo_fdt_remove_node(void *blob, const char *node);
+void karo_fdt_move_fdt(void);
+void karo_fdt_fixup_touchpanel(void *blob, const char *panels[],
+                       size_t num_panels);
+void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy,
+                       const char *phy_supply);
+void karo_fdt_fixup_flexcan(void *blob, int xcvr_present);
+void karo_fdt_del_prop(void *blob, const char *compat, u32 offs,
+               const char *prop);
+void karo_fdt_enable_node(void *blob, const char *node, int enable);
+int karo_fdt_get_fb_mode(void *blob, const char *name,
+               struct fb_videomode *fb_mode);
+int karo_fdt_update_fb_mode(void *blob, const char *name);
+int karo_fdt_create_fb_mode(void *blob, const char *name,
+                       struct fb_videomode *mode);
+int karo_fdt_get_backlight_polarity(const void *blob);
+#else
+static inline void karo_fdt_remove_node(void *blob, const char *node)
+{
+}
+static inline void karo_fdt_move_fdt(void)
+{
+}
+static inline void karo_fdt_fixup_touchpanel(void *blob, const char *panels[],
+                                       size_t num_panels)
+{
+}
+static inline void karo_fdt_fixup_usb_otg(void *blob, const char *node,
+                                       const char *phy,
+                                       const char *phy_supply)
+{
+}
+static inline void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
+{
+}
+static inline void karo_fdt_del_prop(void *blob, const char *compat,
+                               u32 offs, const char *prop)
+{
+}
+static inline void karo_fdt_enable_node(void *blob, const char *node,
+                                       int enable)
+{
+}
+static inline int karo_fdt_get_fb_mode(void *blob, const char *name,
+                               struct fb_videomode *fb_mode)
+{
+       return 0;
+}
+static inline int karo_fdt_update_fb_mode(void *blob, const char *name)
+{
+       return 0;
+}
+static inline int karo_fdt_create_fb_mode(void *blob,
+                                       const char *name,
+                                       struct fb_videomode *mode)
+{
+       return 0;
+}
+static inline int karo_fdt_get_backlight_polarity(const void *blob)
+{
+       return getenv_yesno("backlight_polarity");
+}
+#endif
+
+#if defined(CONFIG_SYS_LVDS_IF) && defined(CONFIG_OF_LIBFDT)
+int karo_fdt_get_lcd_bus_width(const void *blob, int default_width);
+int karo_fdt_get_lvds_mapping(const void *blob, int default_mapping);
+u8 karo_fdt_get_lvds_channels(const void *blob);
+#else
+static inline int karo_fdt_get_lcd_bus_width(const void *blob, int default_width)
+{
+       return default_width;
+}
+static inline int karo_fdt_get_lvds_mapping(const void *blob, int default_mapping)
+{
+       return default_mapping;
+}
+static inline u8 karo_fdt_get_lvds_channels(const void *blob)
+{
+       return 0;
+}
+#endif
+
+static inline const char *karo_get_vmode(const char *video_mode)
+{
+       const char *vmode = NULL;
+
+       if (video_mode == NULL || strlen(video_mode) == 0)
+               return NULL;
+
+       vmode = strchr(video_mode, ':');
+       return vmode ? vmode + 1 : video_mode;
+}
+
+#ifdef CONFIG_SPLASH_SCREEN
+int karo_load_splashimage(int mode);
+#else
+static inline int karo_load_splashimage(int mode)
+{
+       return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_NAND
+int karo_load_nand_part(const char *part, void *addr, size_t len);
+#else
+static inline int karo_load_nand_part(const char *part, void *addr, size_t len)
+{
+       return -EOPNOTSUPP;
+}
+#endif
+
+#ifdef CONFIG_ENV_IS_IN_MMC
+int karo_load_mmc_part(const char *part, void *addr, size_t len);
+#else
+static inline int karo_load_mmc_part(const char *part, void *addr, size_t len)
+{
+       return -EOPNOTSUPP;
+}
+#endif
+
+static inline int karo_load_part(const char *part, void *addr, size_t len)
+{
+       int ret;
+
+       ret = karo_load_nand_part(part, addr, len);
+       if (ret == -EOPNOTSUPP)
+               return karo_load_mmc_part(part, addr, len);
+       return ret;
+}
+
+#define DIV_ROUND(n, d)                (((n) + (d) / 2) / (d))
diff --git a/board/karo/common/mmc.c b/board/karo/common/mmc.c
new file mode 100644 (file)
index 0000000..0048bfb
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * (C) Copyright 2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <mmc.h>
+#include <mxcfb.h>
+#include <fs.h>
+#include <fat.h>
+#include <malloc.h>
+#include <linux/list.h>
+#include <linux/fb.h>
+#include <jffs2/load_kernel.h>
+
+#include "karo.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MAX_SEARCH_PARTITIONS 16
+
+static int find_partitions(const char *ifname, int devno, int fstype,
+                       block_dev_desc_t **dev_desc, disk_partition_t *info)
+{
+       int ret = -1;
+       char *dup_str = NULL;
+       int p;
+       int part;
+       block_dev_desc_t *dd;
+       char dev_part_str[16];
+
+       dd = get_dev(ifname, devno);
+       if (!dd || dd->type == DEV_TYPE_UNKNOWN) {
+               printf("** Bad device %s %d **\n", ifname, devno);
+               return -1;
+       }
+       init_part(dd);
+
+       /*
+        * No partition table on device,
+        * or user requested partition 0 (entire device).
+        */
+       if (dd->part_type == PART_TYPE_UNKNOWN) {
+               printf("** No partition table on device %s %d **\n",
+                       ifname, devno);
+               goto cleanup;
+       }
+
+       part = 0;
+       for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
+               ret = get_partition_info(dd, p, info);
+               if (ret)
+                       continue;
+
+               if (fat_register_device(dd, p) == 0) {
+                       part = p;
+                       dd->log2blksz = LOG2(dd->blksz);
+                       break;
+               }
+       }
+       if (!part) {
+               printf("** No valid partition on device %s %d **\n",
+                       ifname, devno);
+               ret = -1;
+               goto cleanup;
+       }
+       snprintf(dev_part_str, sizeof(dev_part_str), "%d:%d", devno, part);
+       fs_set_blk_dev(ifname, dev_part_str, fstype);
+       ret = part;
+       *dev_desc = dd;
+
+cleanup:
+       free(dup_str);
+       return ret;
+}
+
+static int karo_mmc_find_part(struct mmc *mmc, const char *part, int devno,
+                       disk_partition_t *part_info)
+{
+       int ret;
+       block_dev_desc_t *mmc_dev;
+
+#if defined(CONFIG_SYS_DTB_OFFSET) && defined(CONFIG_SYS_MMC_ENV_PART)
+       if (strcmp(part, "dtb") == 0) {
+               const int partnum = CONFIG_SYS_MMC_ENV_PART;
+
+               part_info->blksz = mmc->read_bl_len;
+               part_info->start = CONFIG_SYS_DTB_OFFSET / part_info->blksz;
+               part_info->size = CONFIG_SYS_DTB_PART_SIZE / part_info->blksz;
+               printf("Using virtual partition %s(%d) ["LBAF".."LBAF"]\n",
+                       part, partnum, part_info->start,
+                       part_info->start + part_info->size - 1);
+               return partnum;
+       }
+#endif
+       ret = find_partitions("mmc", devno, FS_TYPE_FAT, &mmc_dev, part_info);
+       if (ret < 0) {
+               printf("No (e)MMC partition found: %d\n", ret);
+               return ret;
+       }
+       return 0;
+}
+
+int karo_load_mmc_part(const char *part, void *addr, size_t len)
+{
+       int ret;
+       struct mmc *mmc;
+       disk_partition_t part_info;
+       int devno = CONFIG_SYS_MMC_ENV_DEV;
+       lbaint_t blk_cnt;
+       int partnum;
+
+       mmc = find_mmc_device(devno);
+       if (!mmc) {
+               printf("Failed to find mmc%u\n", devno);
+               return -ENODEV;
+       }
+
+       if (mmc_init(mmc)) {
+               printf("Failed to init MMC device %d\n", devno);
+               return -EIO;
+       }
+
+       blk_cnt = DIV_ROUND_UP(len, mmc->read_bl_len);
+
+       partnum = karo_mmc_find_part(mmc, part, devno, &part_info);
+       if (partnum > 0) {
+               if (part_info.start + blk_cnt < part_info.start) {
+                       printf("%s: given length 0x%08x exceeds size of partition\n",
+                               __func__, len);
+                       return -EINVAL;
+               }
+               if (part_info.start + blk_cnt > mmc->block_dev.lba)
+                       blk_cnt = mmc->block_dev.lba - part_info.start;
+
+               mmc_switch_part(devno, partnum);
+
+               memset(addr, 0xee, len);
+
+               debug("Reading 0x"LBAF" blks from MMC partition %d offset 0x"LBAF" to %p\n",
+                       blk_cnt, partnum, part_info.start, addr);
+               ret = mmc->block_dev.block_read(devno, part_info.start, blk_cnt, addr);
+               if (ret == 0) {
+                       printf("Failed to read MMC partition %s\n", part);
+                       ret = -EIO;
+                       goto out;
+               }
+               debug("Read %u (%u) byte from partition '%s' @ offset 0x"LBAF"\n",
+                       ret * mmc->read_bl_len, len, part, part_info.start);
+       } else if (partnum == 0) {
+               loff_t len_read;
+
+               debug("Reading file %s from mmc partition %d\n", part,
+                       partnum);
+               ret = fs_read(part, (ulong)addr, 0, len, &len_read);
+               if (ret < 0) {
+                       printf("Failed to read %u byte from mmc partition %d\n",
+                               len, partnum);
+                       goto out;
+               }
+               if (len_read < len) {
+                       printf("Read only %llu of %u bytes\n", (u64)len_read, len);
+               }
+       } else {
+               ret = partnum;
+               goto out;
+       }
+       ret = 0;
+out:
+       if (partnum > 0)
+               mmc_switch_part(devno, 0);
+       return ret < 0 ? ret : 0;
+}
diff --git a/board/karo/common/nand.c b/board/karo/common/nand.c
new file mode 100644 (file)
index 0000000..6d303f0
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * (C) Copyright 2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+*/
+
+#include <common.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <nand.h>
+#include <mxcfb.h>
+#include <linux/list.h>
+#include <linux/fb.h>
+#include <jffs2/load_kernel.h>
+#include <malloc.h>
+
+#include "karo.h"
+
+#ifdef CONFIG_MAX_DTB_SIZE
+#define MAX_DTB_SIZE   CONFIG_MAX_DTB_SIZE
+#else
+#define MAX_DTB_SIZE   SZ_64K
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int karo_load_nand_part(const char *part, void *addr, size_t len)
+{
+       int ret;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       u8 part_num;
+
+       debug("Initializing mtd_parts\n");
+       ret = mtdparts_init();
+       if (ret)
+               return ret;
+
+       debug("Trying to find NAND partition '%s'\n", part);
+       ret = find_dev_and_part(part, &dev, &part_num, &part_info);
+       if (ret) {
+               printf("Failed to find flash partition '%s': %d\n",
+                       part, ret);
+
+               return ret;
+       }
+       debug("Found partition '%s': offset=%08llx size=%08llx\n",
+               part, (u64)part_info->offset, (u64)part_info->size);
+
+       if (part_info->size < len)
+               len = part_info->size;
+
+       debug("Reading NAND partition '%s' to %p\n", part, addr);
+       ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len,
+                               NULL, part_info->size, addr);
+       if (ret) {
+               printf("Failed to load partition '%s' to %p\n", part, addr);
+               return ret;
+       }
+
+       debug("Read %u byte from partition '%s' @ offset %08llx\n",
+               len, part, (u64)part_info->offset);
+       return 0;
+}
+
+#if defined(CONFIG_SPLASH_SCREEN) && defined(CONFIG_MTDPARTS)
+static int erase_flash(loff_t offs, size_t len)
+{
+       nand_erase_options_t nand_erase_options;
+
+       memset(&nand_erase_options, 0, sizeof(nand_erase_options));
+       nand_erase_options.length = len;
+       nand_erase_options.offset = offs;
+
+       return nand_erase_opts(&nand_info[0], &nand_erase_options);
+}
+
+int do_fbdump(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int ret;
+       size_t fbsize = calc_fbsize();
+       const char *part = "logo";
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       u8 part_num;
+       u_char *addr = (u_char *)gd->fb_base;
+
+       if (argc > 2)
+               return CMD_RET_USAGE;
+
+       if (argc == 2)
+               part = argv[1];
+
+       if (!addr) {
+               printf("fb address unknown\n");
+               return CMD_RET_FAILURE;
+       }
+
+       debug("Initializing mtd_parts\n");
+       ret = mtdparts_init();
+       if (ret)
+               return CMD_RET_FAILURE;
+
+       debug("Trying to find NAND partition '%s'\n", part);
+       ret = find_dev_and_part(part, &dev, &part_num,
+                               &part_info);
+       if (ret) {
+               printf("Failed to find flash partition '%s': %d\n",
+                       part, ret);
+               return CMD_RET_FAILURE;
+       }
+       debug("Found partition '%s': offset=%08x size=%08x\n",
+               part, part_info->offset, part_info->size);
+       if (part_info->size < fbsize) {
+               printf("Error: partition '%s' smaller than frame buffer size: %u\n",
+                       part, fbsize);
+               return CMD_RET_FAILURE;
+       }
+       debug("Writing framebuffer %p to NAND partition '%s'\n",
+               addr, part);
+
+       ret = erase_flash(part_info->offset, fbsize);
+       if (ret) {
+               printf("Failed to erase partition '%s'\n", part);
+               return CMD_RET_FAILURE;
+       }
+
+       ret = nand_write_skip_bad(&nand_info[0], part_info->offset,
+                               &fbsize, NULL, part_info->size,
+                               addr, WITH_DROP_FFS);
+       if (ret) {
+               printf("Failed to write partition '%s'\n", part);
+               return CMD_RET_FAILURE;
+       }
+
+       debug("Wrote %u byte from %p to partition '%s' @ offset %08x\n",
+               fbsize, addr, part, part_info->offset);
+
+       return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(fbdump, 2, 0, do_fbdump, "dump framebuffer contents to flash",
+       "[partition name]\n"
+       "       default partition name: 'logo'\n");
+#endif
diff --git a/board/karo/common/splashimage.c b/board/karo/common/splashimage.c
new file mode 100644 (file)
index 0000000..e39d8d5
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <lcd.h>
+#include <nand.h>
+#include <jffs2/load_kernel.h>
+
+#include "karo.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static ulong calc_fbsize(void)
+{
+       return panel_info.vl_row * panel_info.vl_col *
+               NBITS(panel_info.vl_bpix) / 8;
+}
+
+int karo_load_splashimage(int mode)
+{
+       int ret;
+       unsigned long la = gd->fb_base;
+       char *splashimage = getenv("splashimage");
+       ulong fbsize = calc_fbsize();
+       char *end;
+
+       if (!la || !splashimage)
+               return 0;
+
+       if ((simple_strtoul(splashimage, &end, 16) != 0) &&
+               *end == '\0') {
+               if (mode)
+                       return 0;
+               la = simple_strtoul(splashimage, NULL, 16);
+               splashimage = "logo.bmp";
+       } else if (!mode) {
+               return 0;
+       }
+
+       if (had_ctrlc())
+               return -ENODEV;
+
+       ret = karo_load_part(splashimage, (void *)la, fbsize);
+       if (ret) {
+               printf("Failed to load logo from '%s': %d\n", splashimage, ret);
+               return ret;
+       }
+       return 0;
+}
diff --git a/board/karo/dts/tx28.dts b/board/karo/dts/tx28.dts
new file mode 100644 (file)
index 0000000..b10de03
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2012 <LW@KARO-electronics.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "mx28.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX28 module";
+       compatible = "karo,tx28", "fsl,imx28";
+
+       aliases {
+               usbphy0 = &usbphy0;
+               usbphy1 = &usbphy1;
+               usbotg = &usb0;
+               usbh1 = &usb1;
+               can1 = &can1;
+               ethernet0 = &mac0;
+               ethernet1 = &mac1;
+               ds1339 = &ds1339;
+               pca9554 = &pca9554;
+               stk5led = &stk5_led;
+       };
+
+       memory {
+               reg = <0 0>;
+       };
+
+       apb@80000000 {
+               apbh@80000000 {
+                       ssp0: ssp@80010000 {
+                               compatible = "fsl,imx28-mmc";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&mmc0_4bit_pins_a
+                                            &mmc0_cd_cfg
+                                            &mmc0_sck_cfg>;
+                               bus-width = <4>;
+                               status = "okay";
+                       };
+
+                       pinctrl@80018000 {
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&hog_pins_a>;
+
+                               hog_pins_a: hog-gpios@1 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x31b3 /* MX28_PAD_SPDIF__GPIO_3_27 */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               hog_pins_stk_v3_led: hog-gpios@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x40a3 /* MX28_PAD_ENET0_RXD3__GPIO_4_10 */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               mac0_pins_gpio: mac0-gpio-mode@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x4003 /* MX28_PAD_ENET0_MDC__GPIO_4_0 */
+                                               0x4013 /* MX28_PAD_ENET0_MDIO__GPIO_4_1 */
+                                               0x4023 /* MX28_PAD_ENET0_RX_EN__GPIO_4_2 */
+                                               0x4033 /* MX28_PAD_ENET0_RXD0__GPIO_4_3 */
+                                               0x4043 /* MX28_PAD_ENET0_RXD1__GPIO_4_4 */
+                                               0x4063 /* MX28_PAD_ENET0_TX_EN__GPIO_4_6 */
+                                               0x4073 /* MX28_PAD_ENET0_TXD0__GPIO_4_7 */
+                                               0x4083 /* MX28_PAD_ENET0_TXD1__GPIO_4_8 */
+                                               0x4103 /* MX28_PAD_ENET_CLK__GPIO_4_16 */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               lcdif_pins_tx28: lcdif-tx28@0 {
+                                       fsl,pinmux-ids = <
+                                               0x1181 /* MX28_PAD_LCD_RD_E__LCD_VSYNC */
+                                               0x1191 /* MX28_PAD_LCD_WR_RWN__LCD_HSYNC */
+                                               0x11a1 /* MX28_PAD_LCD_RS__LCD_DOTCLK */
+                                               0x11b1 /* MX28_PAD_LCD_CS__LCD_ENABLE */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+                       };
+
+                       lcdif@80030000 {
+                               status = "okay";
+
+                                pinctrl-names = "default";
+                                pinctrl-0 = <&lcdif_24bit_pins_a
+                                             &lcdif_pins_tx28>;
+                       };
+
+                       can0: can@80032000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&can0_pins_a>;
+                               transceiver-switch = <&flexcan_transceiver>;
+                       };
+
+                       can1: can@80034000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&can1_pins_a>;
+                               transceiver-switch = <&flexcan_transceiver>;
+                       };
+               };
+
+               apbx@80040000 {
+                       saif0: saif@80042000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&saif0_pins_a>;
+                       };
+
+                       saif1: saif@80046000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&saif1_pins_a>;
+                               fsl,saif-master = <&saif0>;
+                       };
+
+                       lradc@80050000 {
+                               status = "okay";
+                       };
+
+                       i2c0: i2c@80058000 {
+                               status = "okay";
+
+                               clock-frequency = <400000>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&i2c0_pins_a>;
+
+                               ds1339: rtc@68 {
+                                       compatible = "maxim,ds1339";
+                                       reg = <0x68>;
+                               };
+
+                               pca9554: pca953x@20 {
+                                       compatible = "nxp,pca953x";
+                                       reg = <0x20>;
+                                       interrupt-parent = <&gpio3>;
+                                       interrupts = <20>;
+                               };
+
+                               codec: sgtl5000@0a {
+                                       compatible = "fsl,sgtl5000";
+                                       reg = <0x0a>;
+                                       VDDA-supply = <&reg_2p5v>;
+                                       VDDIO-supply = <&reg_3p3v>;
+                               };
+
+                               touchscreen: tsc2007@48 {
+                                       compatible = "ti,tsc2007";
+                                       reg = <0x48>;
+                                       interrupt-parent = <&gpio3>;
+                                       interrupts = <20 0>;
+                                       pendown-gpio = <&gpio3 20 1>;
+                                       model = "2007";
+                                       x-plate-ohms = <660>;
+                               };
+
+                               polytouch: edt-ft5x06@ {
+                                       compatible = "edt,edt-ft5x06";
+                                       reg = <0x38>;
+                                       interrupt-parent = <&gpio2>;
+                                       interrupts = <5>;
+                                       reset-switch = <&edt_ft5x06_reset>;
+                                       wake-switch = <&edt_ft5x06_wake>;
+                               };
+                       };
+
+                       pwm: pwm@80064000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pwm0_pins_a>;
+                       };
+
+                       auart1: serial@8006c000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&auart1_pins_a>;
+                       };
+
+                       auart3: serial@80070000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&auart3_pins_a>;
+                       };
+
+                       duart: serial@80074000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&duart_4pins_a>;
+                       };
+
+                       usbphy0: usbphy@8007c000 {
+                               status = "okay";
+                       };
+
+                       usbphy1: usbphy@8007e000 {
+                               status = "okay";
+                       };
+               };
+       };
+
+       ahb@80080000 {
+               usb0: usb@80080000 {
+                       status = "okay";
+
+                        vbus-supply = <&reg_usb0_vbus>;
+                        pinctrl-names = "default";
+               };
+
+               usb1: usb@80090000 {
+                       status = "okay";
+
+                        vbus-supply = <&reg_usb1_vbus>;
+                        pinctrl-names = "default";
+               };
+
+               gpmi-nand@8000c000 {
+                       status = "okay";
+
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&gpmi_pins_a>;
+               };
+
+               mac0: ethernet@800f0000 {
+                       phy-mode = "rmii";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mac0_pins_a>;
+                       status = "okay";
+                       mac-address = [000000000000]; /* will be set bootloader */
+               };
+
+               mac1: ethernet@800f4000 {
+                       phy-mode = "rmii";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&mac1_pins_a>;
+                       status = "okay";
+                       mac-address = [000000000000]; /* will be set by bootloader */
+               };
+       };
+
+       stk5_led: leds {
+               compatible = "gpio-leds";
+
+               user {
+                       label = "Heartbeat";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&hog_pins_stk_v3_led>;
+                       gpios = <&gpio4 10 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm 0 5000000>;
+               brightness-levels = <100 95 90 85 80 75 70 65 60 55
+                                     50 45 40 35 30 25 20 15 10 5 0>;
+               default-brightness-level = <20>;
+       };
+
+       gpio-switch {
+               compatible = "gpio-switches", "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               flexcan_transceiver: gpio-switch@0 {
+                       label = "flexcan transceiver switch";
+                       gpios = <&gpio1 0 1>;
+                       gpio-shared;
+               };
+
+               lcd_power: gpio-switch@1 {
+                       compatible = "linux,gpio-switch";
+                       gpios = <&gpio1 31 0>;
+                       label = "LCD Power Enable";
+                       init-state = <0>;
+               };
+
+               lcd_reset: gpio-switch@2 {
+                       compatible = "linux,gpio-switch";
+                       gpios = <&gpio3 30 1>;
+                       label = "LCD Reset";
+                       init-state = <1>;
+               };
+
+               edt_ft5x06_reset: gpio-switch@3 {
+                       compatible = "linux,gpio-switch";
+                       gpios = <&gpio2 6 1>;
+                       label = "EDT-FT5x06 RESET";
+               };
+
+               edt_ft5x06_wake: gpio-switch@4 {
+                       compatible = "linux,gpio-switch";
+                       gpios = <&gpio4 9 0>;
+                       label = "EDT-FT5x06 WAKE";
+                       init-state = <1>;
+               };
+
+               usbotg_vbus: gpio-switch@5 {
+                       compatible = "linux,gpio-switch";
+                       gpios = <&gpio0 18 0>;
+                       label = "USBOTG VBUS";
+               };
+
+               usbh1_vbus: gpio-switch@6 {
+                       compatible = "linux,gpio-switch";
+                       gpios = <&gpio3 27 0>;
+                       label = "USBH1 VBUS";
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_2p5v: 2p5v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+                reg_usb0_vbus: usb0_vbus {
+                        compatible = "regulator-fixed";
+                        regulator-name = "usb0_vbus";
+                        regulator-min-microvolt = <5000000>;
+                        regulator-max-microvolt = <5000000>;
+                        gpio = <&gpio0 18 1>;
+                };
+
+                reg_usb1_vbus: usb1_vbus {
+                        compatible = "regulator-fixed";
+                        regulator-name = "usb1_vbus";
+                        regulator-min-microvolt = <5000000>;
+                        regulator-max-microvolt = <5000000>;
+                        gpio = <&gpio3 27 1>;
+                };
+       };
+};
diff --git a/board/karo/dts/tx48.dts b/board/karo/dts/tx48.dts
new file mode 100644 (file)
index 0000000..a132836
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX48 module";
+       compatible = "karo,tx48", "ti,am33xx";
+
+       memory {
+               device_type = "memory";
+               reg = <0x80000000 0x10000000>; /* 256 MB */
+       };
+
+       ocp {
+               i2c@44E0B000 {
+                       rtc1: ds1339@68 {
+                               compatible = "dallas,ds1339";
+                               reg = <0x68>;
+                               trickle-charge = <0xa5>;
+                       };
+
+                       pmic: lt3589@48 {
+                               compatible = "lt,lt3589";
+                               reg = <0x48>;
+                       };
+
+                       codec: sgtl5000@0a {
+                               compatible = "fsl,sgtl5000";
+                               reg = <0x0a>;
+                               VDDA-supply = <&reg_2p5v>;
+                               VDDIO-supply = <&reg_3p3v>;
+                       };
+
+                       touchscreen: tsc2007@48 {
+                               compatible = "ti,tsc2007";
+                               reg = <0x48>;
+                               interrupt-parent = <&gpio3>;
+                               interrupts = <16 0>;
+                               pendown-gpio = <&gpio3 16 1>;
+                               model = "2007";
+                               x-plate-ohms = <660>;
+                       };
+
+                       polytouch: edt-ft5x06@38 {
+                               compatible = "edt,edt-ft5x06";
+                               reg = <0x38>;
+                               interrupt-parent = <&gpio1>;
+                               interrupts = <17>;
+                               reset-switch = <&edt_ft5x06_reset>;
+                               wake-switch = <&edt_ft5x06_wake>;
+                       };
+               };
+       };
+
+       gpio-switch {
+               compatible = "gpio-switch";
+
+               can_xcvr_enable: can-xcvr-enable {
+                       gpio = <&gpio0 22 1>;
+                       label = "Flexcan Transceiver Enable";
+                       gpio-shared;
+               };
+
+               lcd_power: lcd-power {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio1 22 0>;
+                       label = "LCD Power Enable";
+               };
+
+               lcd_reset: lcd-reset {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio1 19 1>;
+                       label = "LCD Reset";
+                       init-state = <1>;
+               };
+
+               edt_ft5x06_reset: edt-ft5x06-reset {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio1 18 1>;
+                       label = "EDT-FT5x06 RESET";
+               };
+
+               edt_ft5x06_wake: edt-ft5x06-wake {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio1 27 0>;
+                       label = "EDT-FT5x06 WAKE";
+                       init-state = <1>;
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_2p5v: 2p5v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+};
diff --git a/board/karo/dts/tx51.dts b/board/karo/dts/tx51.dts
new file mode 100644 (file)
index 0000000..22f547e
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright 2012 <LW@KARO-electronics.de>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "mx51.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX51 module";
+       compatible = "karo,tx51", "fsl,imx51";
+
+       chosen {
+               bootargs = "init=/linuxrc console=ttymxc0,115200 root=/dev/mtdblock1 ro debug panic=1";
+       };
+
+       aliases {
+               usbh1 = &usbh1;
+               usbotg = &usbotg;
+               usbphy = &usbphy;
+       };
+
+       clocks {
+               ckih1 {
+                       clock-frequency = <0>;
+               };
+       };
+
+       soc {
+               ahb: ahb@40000000 {
+                       ipu: ipu@5e000000 {
+                               status = "okay";
+                       };
+               };
+
+               aips1: aips@70000000 { /* AIPS1 */
+                       spba@70000000 {
+                               mmc0: esdhc@70004000 { /* ESDHC1 */
+                                       cd-gpios = <&gpio3 8 0>;
+                                       fsl,wp-controller;
+                                       status = "okay";
+                               };
+
+                               mmc1: esdhc@70008000 { /* ESDHC2 */
+                                       cd-gpios = <&gpio3 6 0>;
+                                       status = "okay";
+                               };
+
+                               uart@7000c000 {
+                                       status = "okay";
+                                       fsl,uart-has-rtscts;
+                               };
+
+                               spi0: ecspi@70010000 { /* ECSPI1 */
+                                       fsl,spi-num-chipselects = <2>;
+                                       cs-gpios = <&gpio4 24 0 &gpio4 25 0>;
+                                       status = "okay";
+
+                                       spidev0: spi@0 {
+                                               compatible = "spidev";
+                                               reg = <0>;
+                                               spi-max-frequency = <250000000>;
+                                       };
+                               };
+                       };
+
+                       usbotg: imxotg@73f80000 {
+                               status = "okay";
+
+                               ignore-overcurrent;
+                               enable-wakeup;
+                               phy-mode = "utmi-wide";
+                       };
+
+                       usbh1: imxotg@73f80200 {
+                               status = "okay";
+
+                               phy-mode = "ulpi";
+                               ignore-overcurrent;
+                               enable-wakeup;
+                               itc-no-threshold;
+                       };
+
+                       usbphy: imx-usb-phy@73f80800 {
+                               status = "okay";
+
+                               device-ports = <&usbotg>;
+                               host-ports = <&usbotg &usbh1>;
+                       };
+
+                       keypad@73f94000 {
+                               status = "okay";
+                               /* sample keymap */
+                               linux,keymap = < 0x00000074 /* row 0, col 0, KEY_POWER */
+                                                0x00010052 /* row 0, col 1, KEY_KP0 */
+                                                0x0002004f /* row 0, col 2, KEY_KP1 */
+                                                0x00030050 /* row 0, col 3, KEY_KP2 */
+                                                0x00040051 /* row 0, col 4, KEY_KP3 */
+                                                0x0100004b /* row 1, col 0, KEY_KP4 */
+                                                0x0101004c /* row 1, col 1, KEY_KP5 */
+                                                0x0102004d /* row 1, col 2, KEY_KP6 */
+                                                0x01030047 /* row 1, col 3, KEY_KP7 */
+                                                0x01040048 /* row 1, col 4, KEY_KP8 */
+                                                0x02000049 /* row 2, col 0, KEY_KP9 */
+                                                >;
+                       };
+
+                       wdog@73f98000 { /* WDOG1 */
+                               status = "okay";
+                       };
+
+                       iomuxc@73fa8000 {
+                               compatible = "fsl,imx51-iomuxc-tx51";
+                               reg = <0x73fa8000 0x4000>;
+                       };
+
+                       pwm1: pwm@73fb4000 {
+                               status = "okay";
+                       };
+
+                       uart@73fbc000 {
+                               status = "okay";
+                               fsl,uart-has-rtscts;
+                       };
+
+                       uart@73fc0000 {
+                               status = "okay";
+                               fsl,uart-has-rtscts;
+                       };
+               };
+
+               aips2: aips@80000000 {  /* AIPS2 */
+
+                       sdma@83fb0000 {
+                               fsl,sdma-ram-script-name = "sdma-imx51.bin";
+                       };
+
+                       i2c@83fc4000 { /* I2C2 */
+                               status = "okay";
+
+                               codec: sgtl5000@0a {
+                                       compatible = "fsl,sgtl5000";
+                                       reg = <0x0a>;
+                                       VDDA-supply = <&reg_2p5v>;
+                                       VDDIO-supply = <&reg_3p3v>;
+                               };
+
+                               touchscreen: tsc2007@48 {
+                                       compatible = "ti,tsc2007";
+                                       reg = <0x48>;
+                                       interrupt-parent = <&gpio3>;
+                                       interrupts = <3 0>;
+                                       pendown-gpio = <&gpio3 3 1>;
+                                       model = "2007";
+                                       x-plate-ohms = <660>;
+                               };
+
+                               polytouch: edt-ft5x06@38 {
+                                       compatible = "edt,edt-ft5x06";
+                                       reg = <0x38>;
+                                       interrupt-parent = <&gpio1>;
+                                       interrupts = <5>;
+                                       reset-switch = <&edt_ft5x06_reset>;
+                                       wake-switch = <&edt_ft5x06_wake>;
+                               };
+                       };
+
+                       ssi@83fcc000 {
+                               status = "okay";
+                               rx-dma = <28>;
+                               tx-dma = <29>;
+                               i2s-sync-mode;
+                       };
+
+                       ssi@70014000 {
+                               status = "okay";
+                       };
+
+                       audmux@83fd0000 {
+                               status = "okay";
+                       };
+
+                       sound-card@0 {
+                               compatible = "fsl,imx-sgtl5000";
+                               status = "okay";
+                               /* '1' based port numbers according to datasheet names */
+                               ssi-port = <1>;
+                               audmux-port = <3>;
+                               sysclk = <26000000>;
+                       };
+
+                       nand@83fdb000 {
+                               status = "okay";
+
+                               nand-bus-width = <8>;
+                               nand-ecc-mode = "hw";
+                               nand-on-flash-bbt;
+                       };
+
+                       ethernet@83fec000 {
+                               phy-mode = "mii";
+/*
+                               phy-reset-gpios = <&gpio2 14 0>;
+*/
+                               status = "okay";
+                               phy-handle = <&phy0>;
+                               mac-address = [000000000000];
+
+                               phy0: ethernet-phy@0 {
+                                       interrupt-parent = <&gpio3>;
+                                       interrupts = <18>;
+                                       device_type = "ethernet-phy";
+                               };
+                       };
+               };
+       };
+
+       i2c-gpio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "i2c-gpio";
+               gpios = <&gpio4 17 0
+                        &gpio4 16 0>;
+               clock-frequency = <400000>;
+
+               rtc1: ds1339@68 {
+                       compatible = "dallas,ds1339";
+                       reg = <0x68>;
+               };
+       };
+
+       gpio-switch {
+               compatible = "gpio-switches", "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               lcd_power: gpio-switch@1 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio4 14 0>;
+                       label = "LCD Power Enable";
+                       init-state = <0>;
+               };
+
+               lcd_reset: gpio-switch@2 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio4 13 1>;
+                       label = "LCD Reset";
+                       init-state = <1>;
+               };
+
+               edt_ft5x06_reset: gpio-switch@3 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio4 15 1>;
+                       label = "EDT-FT5x06 RESET";
+               };
+
+               edt_ft5x06_wake: gpio-switch@4 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio4 9 0>;
+                       label = "EDT-FT5x06 WAKE";
+                       init-state = <1>;
+               };
+
+               usbotg_vbus: gpio-switch@5 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio1 8 0>;
+                       label = "USBOTG VBUS";
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               user {
+                       label = "Heartbeat";
+                       gpios = <&gpio4 10 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       lcd {
+               compatible = "of-gpio-lcd";
+               parent = <&ipu>;
+
+               power-switch = <&gpio4 14 0>;
+               reset-switch = <&gpio4 13 1>;
+       };
+
+       backlight: pwm-backlight {
+               compatible = "pwm-backlight";
+
+               pwm = <&pwm1>;
+               inverted;
+               max-brightness = <100>;
+               dft-brightness = <50>;
+               pwm-period-ns = <1000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_2p5v: 2p5v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+};
diff --git a/board/karo/dts/tx53.dts b/board/karo/dts/tx53.dts
new file mode 100644 (file)
index 0000000..0dc6fce
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2012 <LW@KARO-electronics.de>
+ * based on imx53-qsb.dts
+ *   Copyright 2011 Freescale Semiconductor, Inc.
+ *   Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "mx53.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX53 module";
+       compatible = "karo,tx53", "fsl,imx53";
+
+       chosen {
+               bootargs = "init=/linuxrc console=ttymxc0,115200 root=/dev/mtdblock3 rootfstype=jffs2 ro debug panic=1";
+       };
+
+       aliases {
+               ipu = &ipu;
+       };
+
+       clocks {
+               ckih1 {
+                       clock-frequency = <0>;
+               };
+       };
+
+       soc {
+               extmc: extmc@00000000 {
+                       sata: sata@10000000 {
+                               status = "okay";
+                       };
+
+                       ipu: ipu@1e000000 {
+                               status = "okay";
+                       };
+               };
+
+               aips1: aips@50000000 { /* AIPS1 */
+                       spba@50000000 {
+                               mmc0: esdhc@50004000 { /* ESDHC1 */
+                                       status = "okay";
+                                       cd-gpios = <&gpio3 24 0>;
+                                       fsl,wp-controller;
+                               };
+
+                               mmc1: esdhc@50008000 { /* ESDHC2 */
+                                       status = "okay";
+                                       cd-gpios = <&gpio3 25 0>;
+                                       fsl,wp-controller;
+                               };
+
+                               uart3: uart@5000c000 {
+                                       status = "okay";
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <&pinctrl_uart3_1>;
+                                       fsl,uart-has-rtscts;
+                               };
+
+                               spi0: ecspi@50010000 { /* ECSPI1 */
+                                       status = "okay";
+
+                                       pinctrl-names = "default";
+                                       pinctrl-0 = <
+                                               &pinctrl_ecspi1_1
+                                               &pinctrl_cspi1_cs
+                                       >;
+
+                                       fsl,spi-num-chipselects = <2>;
+                                       cs-gpios = <&gpio2 30 0 &gpio3 19 0>;
+
+                                       spidev0: spi@0 {
+                                               compatible = "spidev";
+                                               reg = <0>;
+                                               spi-max-frequency = <54000000>;
+                                       };
+                               };
+                       };
+
+                       usbotg: imxotg@53f80000 {
+                               status = "okay";
+
+                               ignore-overcurrent;
+                               enable-wakeup;
+                               vbus-gpio = <&usbotg_vbus>;
+                       };
+
+                       usbh1: imxotg@53f80200 {
+                               status = "okay";
+
+                               ignore-overcurrent;
+                               enable-wakeup;
+                               vbus-gpio = <&usbh1_vbus>;
+                       };
+
+                       usbphy: imx-usb-phy@53f80800 {
+                               status = "okay";
+
+                               device-ports = <&usbotg>;
+                               host-ports = <&usbotg &usbh1>;
+                       };
+
+                       keypad@53f94000 {
+                               status = "okay";
+                               /* sample keymap */
+                               /* row/col 0,1 are mapped to KPP row/col 6,7 */
+                               linux,keymap = < 0x06060074 /* row 6, col 6, KEY_POWER */
+                                                0x06070052 /* row 6, col 7, KEY_KP0 */
+                                                0x0602004f /* row 6, col 2, KEY_KP1 */
+                                                0x06030050 /* row 6, col 3, KEY_KP2 */
+                                                0x07060051 /* row 7, col 6, KEY_KP3 */
+                                                0x0707004b /* row 7, col 7, KEY_KP4 */
+                                                0x0702004c /* row 7, col 2, KEY_KP5 */
+                                                0x0703004d /* row 7, col 3, KEY_KP6 */
+                                                0x02060047 /* row 2, col 6, KEY_KP7 */
+                                                0x02070048 /* row 2, col 7, KEY_KP8 */
+                                                0x02020049 /* row 2, col 2, KEY_KP9 */
+                                                >;
+                       };
+
+                       wdog@53f98000 { /* WDOG1 */
+                               status = "okay";
+                       };
+
+                       iomuxc@53fa8000 {
+                               compatible = "fsl,imx53-iomuxc-tx53";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_tsc2007_pd>;
+
+                               pincontroller {
+                                       pinctrl_stk5_led: stk5-led-gpios {
+                                               fsl,pins = <
+                                                       589 0xc0 /* MX53_PAD_EIM_A18__GPIO2_20 */
+                                               >;
+                                       };
+
+                                       pinctrl_ds1339_int: ds1339-gpios {
+                                               fsl,pins = <
+                                                       104 0xe0 /* MX53_PAD_DI0_PIN4__GPIO4_20 */
+                                               >;
+                                       };
+
+                                       pinctrl_cspi1_cs: cspi1-cs-gpios {
+                                               fsl,pins = <
+                                                       424 0xe0 /* MX53_PAD_EIM_EB2__GPIO2_30 */
+                                                       449 0xe0 /* MX53_PAD_EIM_D19__GPIO3_19 */
+                                               >;
+                                       };
+
+                                       pinctrl_esdhc1_cd: esdhc1-cd-gpios {
+                                               fsl,pins = <
+                                                       493 0x1f0 /* MX53_PAD_EIM_D24__GPIO3_24 */
+                                               >;
+                                       };
+
+                                       pinctrl_esdhc2_cd: esdhc2-cd-gpios {
+                                               fsl,pins = <
+                                                       501 0x1f0 /* MX53_PAD_EIM_D25__GPIO3_25 */
+                                               >;
+                                       };
+
+                                       pinctrl_tsc2007_pd: pendown-gpios {
+                                               fsl,pins = <
+                                                       517 0x1f0 /* MX53_PAD_EIM_D27__GPIO3_27 */
+                                               >;
+                                       };
+                               };
+                       };
+
+                       pwm2: pwm@53fb8000 {
+                               status = "okay";
+                       };
+
+                       uart1: uart@53fbc000 {
+                               status = "okay";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_uart1_2>;
+                               fsl,uart-has-rtscts;
+                       };
+
+                       uart2: uart@53fc0000 {
+                               status = "okay";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_uart2_1>;
+                               fsl,uart-has-rtscts;
+                       };
+
+                       can1: flexcan@53fc8000 {
+                               status = "okay";
+                               transceiver-switch = <&flexcan_transceiver>;
+                       };
+
+                       can2: flexcan@53fcc000 {
+                               status = "okay";
+                               transceiver-switch = <&flexcan_transceiver>;
+                       };
+
+                       i2c@53fec000 { /* I2C3 */
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_i2c3_1>;
+
+                               sgtl5000: sgtl5000@0a {
+                                       compatible = "fsl,sgtl5000";
+                                       reg = <0x0a>;
+                                       VDDA-supply = <&reg_2p5v>;
+                                       VDDIO-supply = <&reg_3p3v>;
+                                       clock-frequency = <26000000>;
+                               };
+
+                               touchscreen: tsc2007@48 {
+                                       compatible = "ti,tsc2007";
+                                       reg = <0x48>;
+                                       interrupt-parent = <&gpio3>;
+                                       interrupts = <26 0>;
+                                       pendown-gpio = <&gpio3 26 1>;
+                                       model = "2007";
+                                       x-plate-ohms = <660>;
+                               };
+
+                               polytouch: edt-ft5x06@ {
+                                       compatible = "edt,edt-ft5x06";
+                                       reg = <0x38>;
+                                       interrupt-parent = <&gpio6>;
+                                       interrupts = <15 0>;
+                                       reset-switch = <&edt_ft5x06_reset>;
+                                       wake-switch = <&edt_ft5x06_wake>;
+                               };
+                       };
+               };
+
+               aips2: aips@60000000 {  /* AIPS2 */
+
+                       sdma@63fb0000 {
+                               fsl,sdma-ram-script-name = "sdma-imx53.bin";
+                       };
+
+                       i2c@63fc8000 { /* I2C1 */
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <
+                                       &pinctrl_i2c1_2
+                                       &pinctrl_ds1339_int
+                               >;
+
+                               rtc1: ds1339@68 {
+                                       compatible = "dallas,ds1339";
+                                       reg = <0x68>;
+                                       trickle-charge = <0xa5>;
+                                       interrupt-parent = <&gpio4>;
+                                       interrupts = <20 0>;
+                               };
+
+                               pmic: lt3589@48 {
+                                       compatible = "lt,lt3589";
+                                       reg = <0x48>;
+                               };
+                       };
+
+                       ssi@63fcc000 {
+                               status = "okay";
+                               rx-dma = <28>;
+                               tx-dma = <29>;
+                               i2s-sync-mode;
+                       };
+
+                       ssi@50014000 {
+                               status = "okay";
+                       };
+
+                       audmux@63fd0000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_audmux_1>;
+                       };
+
+                       nand@63fdb000 {
+                               status = "okay";
+
+                               nand-bus-width = <8>;
+                               nand-ecc-mode = "hw";
+                               nand-on-flash-bbt;
+                       };
+
+                       ethernet@63fec000 {
+                               status = "okay";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_fec_1>;
+
+                               phy-mode = "rmii";
+                               phy-reset-gpios = <&gpio7 6 0>;
+                               phy-handle = <&phy0>;
+                               mac-address = [000000000000];
+
+                               phy0: ethernet-phy@0 {
+                                       interrupt-parent = <&gpio2>;
+                                       interrupts = <4>;
+                                       device_type = "ethernet-phy";
+                               };
+                       };
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx-sgtl5000";
+               status = "okay";
+               /* '1' based port numbers according to datasheet names */
+               ssi-port = <1>;
+               audmux-port = <5>;
+               sysclk = <26000000>;
+       };
+
+       gpio-switch {
+               compatible = "gpio-switches", "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               flexcan_transceiver: gpio-switch@0 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio4 21 1>;
+                       label = "Flexcan Transceiver Enable";
+                       gpio-shared;
+                       init-state = <0>;
+               };
+
+               lcd_power: gpio-switch@1 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio2 31 0>;
+                       label = "LCD Power Enable";
+                       init-state = <0>;
+               };
+
+               lcd_reset: gpio-switch@2 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio3 29 1>;
+                       label = "LCD Reset";
+                       init-state = <1>;
+               };
+
+               edt_ft5x06_reset: gpio-switch@3 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio2 22 1>;
+                       label = "EDT-FT5x06 RESET";
+               };
+
+               edt_ft5x06_wake: gpio-switch@4 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio2 21 0>;
+                       label = "EDT-FT5x06 WAKE";
+                       init-state = <1>;
+               };
+
+               usbotg_vbus: gpio-switch@5 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio1 7 0>;
+                       label = "USBOTG VBUS";
+               };
+
+               usbh1_vbus: gpio-switch@6 {
+                       compatible = "linux,gpio-switch";
+                       gpio = <&gpio3 31 0>;
+                       label = "USBH1 VBUS";
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_stk5_led>;
+
+               user {
+                       label = "Heartbeat";
+                       gpios = <&gpio2 20 0>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       lcd {
+               compatible = "of-gpio-lcd";
+               parent = <&ipu>;
+
+               power-switch = <&lcd_power>;
+/*
+               reset-switch = <&lcd_reset>;
+               reset-delay-us = <300>;
+*/
+       };
+
+       backlight: pwm-backlight {
+               compatible = "pwm-backlight";
+
+               pwm = <&pwm2>;
+               inverted;
+               max-brightness = <100>;
+               dft-brightness = <50>;
+               pwm-period-ns = <1000000>;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_2p5v: 2p5v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+       };
+};
diff --git a/board/karo/dts/tx6dl.dts b/board/karo/dts/tx6dl.dts
new file mode 100644 (file)
index 0000000..dfbc506
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "mx6dl.dtsi"
+
+/ {
+       model = "Ka-Ro TX6Q module";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+
+       memory {
+               reg = <0 0>; /* filled in by U-Boot */
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1_3 &pinctrl_uart1_4>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2_5 &pinctrl_uart2_6>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3_1 &pinctrl_uart3_4>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet_1>;
+       phy-mode = "rmii";
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1_2>;
+       cd-gpios = <&gpio7 2 0>;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2_2>;
+       cd-gpios = <&gpio7 3 0>;
+       status = "okay";
+};
diff --git a/board/karo/dts/tx6q.dts b/board/karo/dts/tx6q.dts
new file mode 100644 (file)
index 0000000..869c843
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "mx6q.dtsi"
+
+/ {
+       model = "Ka-Ro TX6Q module";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+
+       memory {
+               reg = <0 0>; /* filled in by U-Boot */
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1_3 &pinctrl_uart1_4>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2_5 &pinctrl_uart2_6>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3_1 &pinctrl_uart3_4>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet_1>;
+       phy-mode = "rmii";
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1_2>;
+       cd-gpios = <&gpio7 2 0>;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2_2>;
+       cd-gpios = <&gpio7 3 0>;
+       status = "okay";
+};
diff --git a/board/karo/tx28/Kconfig b/board/karo/tx28/Kconfig
new file mode 100644 (file)
index 0000000..896ee62
--- /dev/null
@@ -0,0 +1,127 @@
+if TARGET_TX28_40X1
+
+config SYS_BOARD
+       default "tx28"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mxs"
+
+config SYS_CONFIG_NAME
+       default "tx28-40x1"
+
+endif
+
+if TARGET_TX28_40X1_NOENV
+
+config SYS_BOARD
+       default "tx28"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mxs"
+
+config SYS_CONFIG_NAME
+       default "tx28-40x1_noenv"
+
+endif
+
+if TARGET_TX28_40X2
+
+config SYS_BOARD
+       default "tx28"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mxs"
+
+config SYS_CONFIG_NAME
+       default "tx28-40x2"
+
+endif
+
+if TARGET_TX28_40X2_NOENV
+
+config SYS_BOARD
+       default "tx28"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mxs"
+
+config SYS_CONFIG_NAME
+       default "tx28-40x2_noenv"
+
+endif
+
+if TARGET_TX28_40X3
+
+config SYS_BOARD
+       default "tx28"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mxs"
+
+config SYS_CONFIG_NAME
+       default "tx28-40x3"
+
+endif
+
+if TARGET_TX28_40X3_NOENV
+
+config SYS_BOARD
+       default "tx28"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mxs"
+
+config SYS_CONFIG_NAME
+       default "tx28-40x3_noenv"
+
+endif
+
+if TARGET_TX28_41X0
+
+config SYS_BOARD
+       default "tx28"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mxs"
+
+config SYS_CONFIG_NAME
+       default "tx28-41x0"
+
+endif
+
+if TARGET_TX28_41X0_NOENV
+
+config SYS_BOARD
+       default "tx28"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mxs"
+
+config SYS_CONFIG_NAME
+       default "tx28-41x0_noenv"
+
+endif
diff --git a/board/karo/tx28/Makefile b/board/karo/tx28/Makefile
new file mode 100644 (file)
index 0000000..698298c
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y                          += tx28.o
+obj-$(CONFIG_SPL_BUILD)                += spl_boot.o
+ifneq ($(CONFIG_SPL_BUILD),y)
+       obj-$(CONFIG_CMD_ROMUPDATE) += flash.o
+endif
diff --git a/board/karo/tx28/config.mk b/board/karo/tx28/config.mk
new file mode 100644 (file)
index 0000000..c3beb5d
--- /dev/null
@@ -0,0 +1,31 @@
+# stack is allocated below CONFIG_SYS_TEXT_BASE
+CONFIG_SYS_TEXT_BASE := 0x40100000
+CONFIG_SPL_TEXT_BASE := 0x00000000
+
+LOGO_BMP = logos/karo.bmp
+
+PLATFORM_CPPFLAGS += -Werror
+ifneq ($(CONFIG_SPL_BUILD),y)
+       ALL-y += $(obj)u-boot.sb
+endif
+
+CONFIG_SYS_NAND_BLOCK_SIZE := 131072
+CONFIG_U_BOOT_PART_SIZE := 1048576
+ifeq ($(CONFIG_SYS_NAND_BLOCKS),)
+CONFIG_SYS_NAND_BLOCKS := 1024
+endif
+CONFIG_SYS_NAND_BBT_BLOCKS := 4
+CONFIG_SYS_NAND_DTB_BLOCKS := 4
+CONFIG_SYS_ENV_BLOCKS := 3
+CONFIG_SYS_LINUX_PART_SIZE := $(shell expr 6 \* 1048576)
+CONFIG_SYS_ROOTFS_PART_SIZE := $(shell expr 32 \* 1048576)
+CONFIG_SYS_SYSTEM_BLOCKS := $(shell expr $(CONFIG_SYS_NAND_BBT_BLOCKS) + $(CONFIG_SYS_NAND_DTB_BLOCKS) + $(CONFIG_SYS_ENV_BLOCKS) + 1)
+CONFIG_SYS_USERFS_SIZE := $(shell expr \( $(CONFIG_SYS_NAND_BLOCKS) - $(CONFIG_SYS_SYSTEM_BLOCKS) \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) - $(CONFIG_U_BOOT_PART_SIZE) - $(CONFIG_SYS_LINUX_PART_SIZE) - $(CONFIG_SYS_ROOTFS_PART_SIZE))
+CONFIG_SYS_USERFS_SIZE2 := $(shell expr \( $(CONFIG_SYS_NAND_BLOCKS) - $(CONFIG_SYS_SYSTEM_BLOCKS) - $(CONFIG_SYS_ENV_BLOCKS) \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) - $(CONFIG_U_BOOT_PART_SIZE) - $(CONFIG_SYS_LINUX_PART_SIZE) - $(CONFIG_SYS_ROOTFS_PART_SIZE))
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_SYSTEM_BLOCKS=$(shell printf "%u" `expr $(CONFIG_SYS_SYSTEM_BLOCKS)`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_ENV_PART_SIZE=$(shell printf "%uk" `expr $(CONFIG_SYS_ENV_BLOCKS) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) / 1024`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BBT_OFFSET=$(shell printf "0x%x" `expr \( $(CONFIG_SYS_NAND_BLOCKS) - $(CONFIG_SYS_NAND_BBT_BLOCKS) \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE)`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BLOCKS=$(CONFIG_SYS_NAND_BLOCKS)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_DTB_OFFSET=$(shell printf "0x%x" `expr \( $(CONFIG_SYS_NAND_BLOCKS) - $(CONFIG_SYS_NAND_DTB_BLOCKS) - $(CONFIG_SYS_NAND_BBT_BLOCKS) \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE)`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_USERFS_PART_SIZE=$(shell printf "%uk" `expr $(CONFIG_SYS_USERFS_SIZE) / 1024`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_USERFS_PART_SIZE2=$(shell printf "%uk" `expr $(CONFIG_SYS_USERFS_SIZE2) / 1024`)
diff --git a/board/karo/tx28/flash.c b/board/karo/tx28/flash.c
new file mode 100644 (file)
index 0000000..9234e72
--- /dev/null
@@ -0,0 +1,663 @@
+/*
+ * Copyright (C) 2011-2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <nand.h>
+#include <errno.h>
+
+#include <linux/err.h>
+#include <jffs2/load_kernel.h>
+
+#include <asm/io.h>
+#include <linux/sizes.h>
+#include <asm/arch/regs-base.h>
+#include <asm/imx-common/regs-gpmi.h>
+#include <asm/imx-common/regs-bch.h>
+
+struct mx28_nand_timing {
+       u8 data_setup;
+       u8 data_hold;
+       u8 address_setup;
+       u8 dsample_time;
+       u8 nand_timing_state;
+       u8 tREA;
+       u8 tRLOH;
+       u8 tRHOH;
+};
+
+struct mx28_fcb {
+       u32 checksum;
+       u32 fingerprint;
+       u32 version;
+       struct mx28_nand_timing timing;
+       u32 page_data_size;
+       u32 total_page_size;
+       u32 sectors_per_block;
+       u32 number_of_nands;    /* not used by ROM code */
+       u32 total_internal_die; /* not used by ROM code */
+       u32 cell_type;          /* not used by ROM code */
+       u32 ecc_blockn_type;
+       u32 ecc_block0_size;
+       u32 ecc_blockn_size;
+       u32 ecc_block0_type;
+       u32 metadata_size;
+       u32 ecc_blocks_per_page;
+       u32 rsrvd[6];            /* not used by ROM code */
+       u32 bch_mode;
+       u32 boot_patch;
+       u32 patch_sectors;
+       u32 fw1_start_page;
+       u32 fw2_start_page;
+       u32 fw1_sectors;
+       u32 fw2_sectors;
+       u32 dbbt_search_area;
+       u32 bb_mark_byte;
+       u32 bb_mark_startbit;
+       u32 bb_mark_phys_offset;
+};
+
+#define BF_VAL(v, bf)          (((v) & bf##_MASK) >> bf##_OFFSET)
+
+static nand_info_t *mtd = &nand_info[0];
+
+extern void *_start;
+
+#define BIT(v,n)       (((v) >> (n)) & 0x1)
+
+static u8 calculate_parity_13_8(u8 d)
+{
+       u8 p = 0;
+
+       p |= (BIT(d, 6) ^ BIT(d, 5) ^ BIT(d, 3) ^ BIT(d, 2))             << 0;
+       p |= (BIT(d, 7) ^ BIT(d, 5) ^ BIT(d, 4) ^ BIT(d, 2) ^ BIT(d, 1)) << 1;
+       p |= (BIT(d, 7) ^ BIT(d, 6) ^ BIT(d, 5) ^ BIT(d, 1) ^ BIT(d, 0)) << 2;
+       p |= (BIT(d, 7) ^ BIT(d, 4) ^ BIT(d, 3) ^ BIT(d, 0))             << 3;
+       p |= (BIT(d, 6) ^ BIT(d, 4) ^ BIT(d, 3) ^ BIT(d, 2) ^ BIT(d, 1) ^ BIT(d, 0)) << 4;
+       return p;
+}
+
+static void encode_hamming_13_8(void *_src, void *_ecc, size_t size)
+{
+       int i;
+       u8 *src = _src;
+       u8 *ecc = _ecc;
+
+       for (i = 0; i < size; i++)
+               ecc[i] = calculate_parity_13_8(src[i]);
+}
+
+static u32 calc_chksum(void *buf, size_t size)
+{
+       u32 chksum = 0;
+       u8 *bp = buf;
+       size_t i;
+
+       for (i = 0; i < size; i++) {
+               chksum += bp[i];
+       }
+       return ~chksum;
+}
+
+/*
+  Physical organisation of data in NAND flash:
+  metadata
+  payload chunk 0 (may be empty)
+  ecc for metadata + payload chunk 0
+  payload chunk 1
+  ecc for payload chunk 1
+...
+  payload chunk n
+  ecc for payload chunk n
+ */
+
+static int calc_bb_offset(nand_info_t *mtd, struct mx28_fcb *fcb)
+{
+       int bb_mark_offset;
+       int chunk_data_size = fcb->ecc_blockn_size * 8;
+       int chunk_ecc_size = (fcb->ecc_blockn_type << 1) * 13;
+       int chunk_total_size = chunk_data_size + chunk_ecc_size;
+       int bb_mark_chunk, bb_mark_chunk_offs;
+
+       bb_mark_offset = (mtd->writesize - fcb->metadata_size) * 8;
+       if (fcb->ecc_block0_size == 0)
+               bb_mark_offset -= (fcb->ecc_block0_type << 1) * 13;
+
+       bb_mark_chunk = bb_mark_offset / chunk_total_size;
+       bb_mark_chunk_offs = bb_mark_offset - (bb_mark_chunk * chunk_total_size);
+       if (bb_mark_chunk_offs > chunk_data_size) {
+               printf("Unsupported ECC layout; BB mark resides in ECC data: %u\n",
+                       bb_mark_chunk_offs);
+               return -EINVAL;
+       }
+       bb_mark_offset -= bb_mark_chunk * chunk_ecc_size;
+       return bb_mark_offset;
+}
+
+/*
+ * return number of blocks to skip for a contiguous partition
+ * of given # blocks
+ */
+static int find_contig_space(int block, int num_blocks, int max_blocks)
+{
+       int skip = 0;
+       int found = 0;
+       int last = block + max_blocks;
+
+       debug("Searching %u contiguous blocks from %d..%d\n",
+               num_blocks, block, block + max_blocks - 1);
+       for (; block < last; block++) {
+               if (nand_block_isbad(mtd, block * mtd->erasesize)) {
+                       skip += found + 1;
+                       found = 0;
+                       debug("Skipping %u blocks to %u\n",
+                               skip, block + 1);
+               } else {
+                       found++;
+                       if (found >= num_blocks) {
+                               debug("Found %u good blocks from %d..%d\n",
+                                       found, block - found + 1, block);
+                               return skip;
+                       }
+               }
+       }
+       return -ENOSPC;
+}
+
+#define pr_fcb_val(p, n)       debug("%s=%08x(%d)\n", #n, (p)->n, (p)->n)
+
+static struct mx28_fcb *create_fcb(void *buf, int fw1_start_block,
+                               int fw2_start_block, int fw_num_blocks)
+{
+       struct gpmi_regs *gpmi_base = (void *)GPMI_BASE_ADDRESS;
+       struct bch_regs *bch_base = (void *)BCH_BASE_ADDRESS;
+       u32 fl0, fl1;
+       u32 t0;
+       int metadata_size;
+       int bb_mark_bit_offs;
+       struct mx28_fcb *fcb;
+       int fcb_offs;
+
+       if (gpmi_base == NULL || bch_base == NULL) {
+               return ERR_PTR(-ENOMEM);
+       }
+
+       fl0 = readl(&bch_base->hw_bch_flash0layout0);
+       fl1 = readl(&bch_base->hw_bch_flash0layout1);
+       t0 = readl(&gpmi_base->hw_gpmi_timing0);
+
+       metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+
+       fcb = buf + ALIGN(metadata_size, 4);
+       fcb_offs = (void *)fcb - buf;
+
+       memset(buf, 0xff, fcb_offs);
+       memset(fcb, 0x00, sizeof(*fcb));
+       memset(fcb + 1, 0xff, mtd->erasesize - fcb_offs - sizeof(*fcb));
+
+       strncpy((char *)&fcb->fingerprint, "FCB ", 4);
+       fcb->version = cpu_to_be32(1);
+
+       /* ROM code assumes GPMI clock of 25 MHz */
+       fcb->timing.data_setup = BF_VAL(t0, GPMI_TIMING0_DATA_SETUP) * 40;
+       fcb->timing.data_hold = BF_VAL(t0, GPMI_TIMING0_DATA_HOLD) * 40;
+       fcb->timing.address_setup = BF_VAL(t0, GPMI_TIMING0_ADDRESS_SETUP) * 40;
+
+       fcb->page_data_size = mtd->writesize;
+       fcb->total_page_size = mtd->writesize + mtd->oobsize;
+       fcb->sectors_per_block = mtd->erasesize / mtd->writesize;
+
+       fcb->ecc_block0_type = BF_VAL(fl0, BCH_FLASHLAYOUT0_ECC0);
+       fcb->ecc_block0_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_DATA0_SIZE);
+       fcb->ecc_blockn_type = BF_VAL(fl1, BCH_FLASHLAYOUT1_ECCN);
+       fcb->ecc_blockn_size = BF_VAL(fl1, BCH_FLASHLAYOUT1_DATAN_SIZE);
+
+       pr_fcb_val(fcb, ecc_block0_type);
+       pr_fcb_val(fcb, ecc_blockn_type);
+       pr_fcb_val(fcb, ecc_block0_size);
+       pr_fcb_val(fcb, ecc_blockn_size);
+
+       fcb->metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+       fcb->ecc_blocks_per_page = BF_VAL(fl0, BCH_FLASHLAYOUT0_NBLOCKS);
+       fcb->bch_mode = readl(&bch_base->hw_bch_mode);
+
+       fcb->fw1_start_page = fw1_start_block * fcb->sectors_per_block;
+       fcb->fw1_sectors = fw_num_blocks * fcb->sectors_per_block;
+       pr_fcb_val(fcb, fw1_start_page);
+       pr_fcb_val(fcb, fw1_sectors);
+
+       if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
+               fcb->fw2_start_page = fw2_start_block * fcb->sectors_per_block;
+               fcb->fw2_sectors = fcb->fw1_sectors;
+               pr_fcb_val(fcb, fw2_start_page);
+               pr_fcb_val(fcb, fw2_sectors);
+       }
+
+       fcb->dbbt_search_area = 1;
+
+       bb_mark_bit_offs = calc_bb_offset(mtd, fcb);
+       if (bb_mark_bit_offs < 0)
+               return ERR_PTR(bb_mark_bit_offs);
+       fcb->bb_mark_byte = bb_mark_bit_offs / 8;
+       fcb->bb_mark_startbit = bb_mark_bit_offs % 8;
+       fcb->bb_mark_phys_offset = mtd->writesize;
+
+       pr_fcb_val(fcb, bb_mark_byte);
+       pr_fcb_val(fcb, bb_mark_startbit);
+       pr_fcb_val(fcb, bb_mark_phys_offset);
+
+       fcb->checksum = calc_chksum(&fcb->fingerprint, 512 - 4);
+       return fcb;
+}
+
+static int find_fcb(void *ref, int page)
+{
+       int ret = 0;
+       struct nand_chip *chip = mtd->priv;
+       void *buf = malloc(mtd->erasesize);
+
+       if (buf == NULL) {
+               return -ENOMEM;
+       }
+       chip->select_chip(mtd, 0);
+       chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+       ret = chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
+       if (ret) {
+               printf("Failed to read FCB from page %u: %d\n", page, ret);
+               goto out;
+       }
+       if (memcmp(buf, ref, mtd->writesize) == 0) {
+               debug("Found FCB in page %u (%08x)\n",
+                       page, page * mtd->writesize);
+               ret = 1;
+       }
+out:
+       chip->select_chip(mtd, -1);
+       free(buf);
+       return ret;
+}
+
+static int write_fcb(void *buf, int block)
+{
+       int ret;
+       struct nand_chip *chip = mtd->priv;
+       int page = block * mtd->erasesize / mtd->writesize;
+
+       ret = find_fcb(buf, page);
+       if (ret > 0) {
+               printf("FCB at block %d is up to date\n", block);
+               return 0;
+       }
+
+       ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
+       if (ret) {
+               printf("Failed to erase FCB block %u\n", block);
+               return ret;
+       }
+
+       printf("Writing FCB to block %d @ %08llx\n", block,
+               (u64)block * mtd->erasesize);
+       chip->select_chip(mtd, 0);
+       ret = chip->write_page(mtd, chip, buf, 1, page, 0, 1);
+       if (ret) {
+               printf("Failed to write FCB to block %u: %d\n", block, ret);
+       }
+       chip->select_chip(mtd, -1);
+       return ret;
+}
+
+#define chk_overlap(a,b)                               \
+       ((a##_start_block <= b##_end_block &&           \
+               a##_end_block >= b##_start_block) ||    \
+       (b##_start_block <= a##_end_block &&            \
+               b##_end_block >= a##_start_block))
+
+#define fail_if_overlap(a,b,m1,m2) do {                                \
+       if (chk_overlap(a, b)) {                                \
+               printf("%s blocks %lu..%lu overlap %s in blocks %lu..%lu!\n", \
+                       m1, a##_start_block, a##_end_block,     \
+                       m2, b##_start_block, b##_end_block);    \
+               return -EINVAL;                                 \
+       }                                                       \
+} while (0)
+
+static int tx28_prog_uboot(void *addr, int start_block, int skip,
+                       size_t size, size_t max_len)
+{
+       int ret;
+       nand_erase_options_t erase_opts = { 0, };
+       size_t actual;
+       size_t prg_length = max_len - skip * mtd->erasesize;
+       int prg_start = (start_block + skip) * mtd->erasesize;
+
+       erase_opts.offset = start_block * mtd->erasesize;
+       erase_opts.length = max_len;
+       erase_opts.quiet = 1;
+
+       printf("Erasing flash @ %08llx..%08llx\n", erase_opts.offset,
+               erase_opts.offset + erase_opts.length - 1);
+       ret = nand_erase_opts(mtd, &erase_opts);
+       if (ret) {
+               printf("Failed to erase flash: %d\n", ret);
+               return ret;
+       }
+
+       printf("Programming flash @ %08llx..%08llx from %p\n",
+               (u64)start_block * mtd->erasesize,
+               (u64)start_block * mtd->erasesize + size - 1, addr);
+       actual = size;
+       ret = nand_write_skip_bad(mtd, prg_start, &actual, NULL,
+                               prg_length, addr, WITH_DROP_FFS);
+       if (ret) {
+               printf("Failed to program flash: %d\n", ret);
+               return ret;
+       }
+       if (actual < size) {
+               printf("Could only write %u of %u bytes\n", actual, size);
+               return -EIO;
+       }
+       return 0;
+}
+
+#ifdef CONFIG_ENV_IS_IN_NAND
+#ifndef CONFIG_ENV_OFFSET_REDUND
+#define TOTAL_ENV_SIZE CONFIG_ENV_RANGE
+#else
+#define TOTAL_ENV_SIZE (CONFIG_ENV_RANGE * 2)
+#endif
+#endif
+
+int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int ret;
+       const unsigned long fcb_start_block = 0, fcb_end_block = 0;
+       int erase_size = mtd->erasesize;
+       int page_size = mtd->writesize;
+       void *buf;
+       char *load_addr;
+       char *file_size;
+       size_t size = 0;
+       void *addr = NULL;
+       struct mx28_fcb *fcb;
+       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+#ifdef CONFIG_ENV_IS_IN_NAND
+       unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
+       unsigned long env_end_block = env_start_block +
+               DIV_ROUND_UP(TOTAL_ENV_SIZE, mtd->erasesize) - 1;
+#endif
+       int optind;
+       int fw2_set = 0;
+       unsigned long fw1_start_block = 0, fw1_end_block;
+       unsigned long fw2_start_block = 0, fw2_end_block;
+       unsigned long fw_num_blocks;
+       int fw1_skip, fw2_skip;
+       unsigned long extra_blocks = 0;
+       size_t max_len1, max_len2;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       struct part_info *redund_part_info;
+       const char *uboot_part = "u-boot";
+       const char *redund_part = NULL;
+       u8 part_num;
+       u8 redund_part_num;
+
+       ret = mtdparts_init();
+       if (ret)
+               return ret;
+
+       for (optind = 1; optind < argc; optind++) {
+               char *endp;
+
+               if (strcmp(argv[optind], "-f") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       fw1_start_block = simple_strtoul(argv[optind], &endp, 0);
+                       if (*endp != '\0') {
+                               uboot_part = argv[optind];
+                               continue;
+                       }
+                       uboot_part = NULL;
+                       if (fw1_start_block >= mtd_num_blocks) {
+                               printf("Block number %lu is out of range: 0..%lu\n",
+                                       fw1_start_block, mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (strcmp(argv[optind], "-r") == 0) {
+                       fw2_set = 1;
+                       if (optind < argc - 1 && argv[optind + 1][0] != '-') {
+                               optind++;
+                               fw2_start_block = simple_strtoul(argv[optind],
+                                                               &endp, 0);
+                               if (*endp != '\0') {
+                                       redund_part = argv[optind];
+                                       continue;
+                               }
+                               if (fw2_start_block >= mtd_num_blocks) {
+                                       printf("Block number %lu is out of range: 0..%lu\n",
+                                               fw2_start_block,
+                                               mtd_num_blocks - 1);
+                                       return -EINVAL;
+                               }
+                       }
+               } else if (strcmp(argv[optind], "-e") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       extra_blocks = simple_strtoul(argv[optind], NULL, 0);
+                       if (extra_blocks >= mtd_num_blocks) {
+                               printf("Extra block count %lu is out of range: 0..%lu\n",
+                                       extra_blocks,
+                                       mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (argv[optind][0] == '-') {
+                       printf("Unrecognized option %s\n", argv[optind]);
+                       return -EINVAL;
+               } else {
+                       break;
+               }
+       }
+
+       load_addr = getenv("fileaddr");
+       file_size = getenv("filesize");
+
+       if (argc - optind < 1 && load_addr == NULL) {
+               printf("Load address not specified\n");
+               return -EINVAL;
+       }
+       if (argc - optind < 2 && file_size == NULL) {
+               printf("WARNING: Image size not specified; overwriting whole uboot partition\n");
+       }
+       if (argc > optind) {
+               load_addr = NULL;
+               addr = (void *)simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (argc > optind) {
+               file_size = NULL;
+               size = simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (load_addr != NULL) {
+               addr = (void *)simple_strtoul(load_addr, NULL, 16);
+               printf("Using default load address %p\n", addr);
+       }
+       if (file_size != NULL) {
+               size = simple_strtoul(file_size, NULL, 16);
+               printf("Using default file size %08x\n", size);
+       }
+       if (size > 0) {
+               fw_num_blocks = DIV_ROUND_UP(size, mtd->erasesize);
+       } else {
+               fw_num_blocks = part_info->size / mtd->erasesize -
+                       extra_blocks;
+               size = fw_num_blocks * mtd->erasesize;
+       }
+
+       if (uboot_part) {
+               ret = find_dev_and_part(uboot_part, &dev, &part_num,
+                                       &part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               uboot_part, ret);
+                       return ret;
+               }
+               fw1_start_block = part_info->offset / mtd->erasesize;
+               max_len1 = part_info->size;
+       } else {
+               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       }
+
+       if (redund_part) {
+               ret = find_dev_and_part(redund_part, &dev, &redund_part_num,
+                                       &redund_part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               redund_part, ret);
+                       return ret;
+               }
+               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               max_len2 = redund_part_info->size;
+       } else if (fw2_set) {
+               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       } else {
+               max_len2 = 0;
+       }
+
+       fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
+                               max_len1 / mtd->erasesize);
+       if (fw1_skip < 0) {
+               printf("Could not find %lu contiguous good blocks for fw image\n",
+                       fw_num_blocks);
+               if (uboot_part) {
+#ifdef CONFIG_ENV_IS_IN_NAND
+                       if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
+                               printf("Use a different partition\n");
+                       } else {
+                               printf("Increase the size of the '%s' partition\n",
+                                       uboot_part);
+                       }
+#else
+                       printf("Increase the size of the '%s' partition\n",
+                               uboot_part);
+#endif
+               } else {
+                       printf("Increase the number of spare blocks to use with the '-e' option\n");
+               }
+               return -ENOSPC;
+       }
+       fw1_end_block = fw1_start_block + fw1_skip + fw_num_blocks - 1;
+
+       if (fw2_set && fw2_start_block == 0)
+               fw2_start_block = fw1_end_block + 1;
+       if (fw2_start_block > 0) {
+               fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
+                                       max_len2 / mtd->erasesize);
+               if (fw2_skip < 0) {
+                       printf("Could not find %lu contiguous good blocks for redundant fw image\n",
+                               fw_num_blocks);
+                       if (redund_part) {
+                               printf("Increase the size of the '%s' partition or use a different partition\n",
+                                       redund_part);
+                       } else {
+                               printf("Increase the number of spare blocks to use with the '-e' option\n");
+                       }
+                       return -ENOSPC;
+               }
+       } else {
+               fw2_skip = 0;
+       }
+       fw2_end_block = fw2_start_block + fw2_skip + fw_num_blocks - 1;
+
+#ifdef CONFIG_ENV_IS_IN_NAND
+       fail_if_overlap(fcb, env, "FCB", "Environment");
+       fail_if_overlap(fw1, env, "FW1", "Environment");
+#endif
+       fail_if_overlap(fcb, fw1, "FCB", "FW1");
+       if (fw2_set) {
+               fail_if_overlap(fcb, fw2, "FCB", "FW2");
+#ifdef CONFIG_ENV_IS_IN_NAND
+               fail_if_overlap(fw2, env, "FW2", "Environment");
+#endif
+               fail_if_overlap(fw1, fw2, "FW1", "FW2");
+       }
+
+       buf = malloc(erase_size);
+       if (buf == NULL) {
+               printf("Failed to allocate buffer\n");
+               return -ENOMEM;
+       }
+
+       fcb = create_fcb(buf, fw1_start_block + fw1_skip,
+                       fw2_start_block + fw2_skip, fw_num_blocks);
+       if (IS_ERR(fcb)) {
+               printf("Failed to initialize FCB: %ld\n", PTR_ERR(fcb));
+               free(buf);
+               return PTR_ERR(fcb);
+       }
+       encode_hamming_13_8(fcb, (void *)fcb + 512, 512);
+
+       ret = write_fcb(buf, fcb_start_block);
+       free(buf);
+       if (ret) {
+               printf("Failed to write FCB to block %lu\n", fcb_start_block);
+               return ret;
+       }
+
+       if (size & (page_size - 1)) {
+               memset(addr + size, 0xff, size & (page_size - 1));
+               size = ALIGN(size, page_size);
+       }
+
+       printf("Programming U-Boot image from %p to block %lu @ %08llx\n",
+               addr, fw1_start_block + fw1_skip,
+               (u64)(fw1_start_block + fw1_skip) * mtd->erasesize);
+       ret = tx28_prog_uboot(addr, fw1_start_block, fw1_skip, size,
+                       max_len1);
+
+       if (fw2_start_block == 0) {
+               return ret;
+       }
+
+       printf("Programming redundant U-Boot image to block %lu @ %08llx\n",
+               fw2_start_block + fw2_skip,
+               (u64)(fw2_start_block + fw2_skip) * mtd->erasesize);
+       ret = tx28_prog_uboot(addr, fw2_start_block, fw2_skip, fw_num_blocks,
+                       max_len2);
+       return ret;
+}
+
+U_BOOT_CMD(romupdate, 11, 0, do_update,
+       "Creates an FCB data structure and writes an U-Boot image to flash",
+       "[-f {<part>|block#}] [-r [{<part>|block#}]] [-e #] [<address>] [<length>]\n"
+       "\t-f <part>\twrite bootloader image to partition <part>\n"
+       "\t-f #\twrite bootloader image at block # (decimal)\n"
+       "\t-r\twrite redundant bootloader image at next free block after first image\n"
+       "\t-r <part>\twrite redundant bootloader image to partition <part>\n"
+       "\t-r #\twrite redundant bootloader image at block # (decimal)\n"
+       "\t-e #\tspecify number of redundant blocks per boot loader image\n"
+       "\t\tonly valid if -f or -r specify a flash address rather than a partition name\n"
+       "\t<address>\tRAM address of bootloader image (default: ${fileaddr}\n"
+       "\t<length>\tlength of bootloader image in RAM (default: ${filesize}"
+       );
diff --git a/board/karo/tx28/spl_boot.c b/board/karo/tx28/spl_boot.c
new file mode 100644 (file)
index 0000000..58335ff
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2011 Lothar Waßmann <LW@KARO-electronics.de>
+ * based on: board/freesclae/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/iomux-mx28.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+
+#define        MUX_CONFIG_LED  (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
+#define        MUX_CONFIG_LCD  (MXS_PAD_3V3 | MXS_PAD_4MA)
+#define        MUX_CONFIG_TSC  (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP)
+#define        MUX_CONFIG_SSP0 (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_PULLUP)
+#define        MUX_CONFIG_SSP2 (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
+#define        MUX_CONFIG_GPMI (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
+#define        MUX_CONFIG_ENET (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
+#define        MUX_CONFIG_EMI  (MXS_PAD_1V8 | MXS_PAD_12MA | MXS_PAD_NOPULL)
+#define MUX_CONFIG_GPIO (MXS_PAD_3V3 | MXS_PAD_PULLUP)
+
+static iomux_cfg_t tx28_stk5_pads[] = {
+       /* LED */
+       MX28_PAD_ENET0_RXD3__GPIO_4_10 | MUX_CONFIG_LED,
+
+       /* framebuffer */
+       MX28_PAD_LCD_D00__LCD_D0 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D01__LCD_D1 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D02__LCD_D2 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D03__LCD_D3 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D04__LCD_D4 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D05__LCD_D5 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D06__LCD_D6 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D07__LCD_D7 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D08__LCD_D8 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D09__LCD_D9 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D10__LCD_D10 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D11__LCD_D11 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D12__LCD_D12 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D13__LCD_D13 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D14__LCD_D14 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D15__LCD_D15 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D16__LCD_D16 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D17__LCD_D17 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D18__LCD_D18 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D19__LCD_D19 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D20__LCD_D20 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D21__LCD_D21 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D22__LCD_D22 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_D23__LCD_D23 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_RD_E__LCD_VSYNC | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_WR_RWN__LCD_HSYNC | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_RS__LCD_DOTCLK | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_CS__LCD_CS | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_VSYNC__LCD_VSYNC | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_HSYNC__LCD_HSYNC | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_DOTCLK__LCD_DOTCLK | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_ENABLE__GPIO_1_31 | MUX_CONFIG_LCD,
+       MX28_PAD_LCD_RESET__GPIO_3_30 | MUX_CONFIG_LCD,
+
+       /* DUART pads */
+       MX28_PAD_PWM0__GPIO_3_16 | MUX_CONFIG_GPIO,
+       MX28_PAD_PWM1__GPIO_3_17 | MUX_CONFIG_GPIO,
+       MX28_PAD_I2C0_SCL__GPIO_3_24 | MUX_CONFIG_GPIO,
+       MX28_PAD_I2C0_SDA__GPIO_3_25 | MUX_CONFIG_GPIO,
+
+       MX28_PAD_AUART0_RTS__DUART_TX,
+       MX28_PAD_AUART0_CTS__DUART_RX,
+       MX28_PAD_AUART0_TX__DUART_RTS,
+       MX28_PAD_AUART0_RX__DUART_CTS,
+
+       /* EMI */
+       MX28_PAD_EMI_D00__EMI_DATA0 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D01__EMI_DATA1 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D02__EMI_DATA2 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D03__EMI_DATA3 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D04__EMI_DATA4 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D05__EMI_DATA5 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D06__EMI_DATA6 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D07__EMI_DATA7 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D08__EMI_DATA8 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D09__EMI_DATA9 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D10__EMI_DATA10 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D11__EMI_DATA11 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D12__EMI_DATA12 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D13__EMI_DATA13 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D14__EMI_DATA14 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_D15__EMI_DATA15 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_ODT0__EMI_ODT0 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_DQM0__EMI_DQM0 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_ODT1__EMI_ODT1 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_DQM1__EMI_DQM1 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_CLK__EMI_CLK | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_DQS0__EMI_DQS0 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_DQS1__EMI_DQS1 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN | MUX_CONFIG_EMI,
+
+       MX28_PAD_EMI_A00__EMI_ADDR0 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A01__EMI_ADDR1 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A02__EMI_ADDR2 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A03__EMI_ADDR3 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A04__EMI_ADDR4 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A05__EMI_ADDR5 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A06__EMI_ADDR6 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A07__EMI_ADDR7 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A08__EMI_ADDR8 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A09__EMI_ADDR9 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A10__EMI_ADDR10 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A11__EMI_ADDR11 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A12__EMI_ADDR12 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A13__EMI_ADDR13 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_A14__EMI_ADDR14 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_BA0__EMI_BA0 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_BA1__EMI_BA1 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_BA2__EMI_BA2 | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_CASN__EMI_CASN | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_RASN__EMI_RASN | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_WEN__EMI_WEN | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_CE0N__EMI_CE0N | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_CE1N__EMI_CE1N | MUX_CONFIG_EMI,
+       MX28_PAD_EMI_CKE__EMI_CKE | MUX_CONFIG_EMI,
+
+       /* FEC pads */
+       MX28_PAD_PWM4__GPIO_3_29 | MUX_CONFIG_ENET,
+       MX28_PAD_ENET0_RX_CLK__GPIO_4_13 | MUX_CONFIG_ENET,
+       MX28_PAD_ENET0_MDC__ENET0_MDC | MUX_CONFIG_ENET,
+       MX28_PAD_ENET0_MDIO__ENET0_MDIO | MUX_CONFIG_ENET,
+       MX28_PAD_ENET0_RX_EN__GPIO_4_2 | MUX_CONFIG_ENET,       /* COL/CRS_DV/MODE2 */
+       MX28_PAD_ENET0_RXD0__GPIO_4_3 | MUX_CONFIG_ENET,        /* RXD0/MODE0 */
+       MX28_PAD_ENET0_RXD1__GPIO_4_4 | MUX_CONFIG_ENET,        /* RXD1/MODE1 */
+       MX28_PAD_ENET0_TX_CLK__GPIO_4_5 | MUX_CONFIG_ENET,      /* nINT/TX_ER/TXD4 */
+       MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MUX_CONFIG_ENET,
+       MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MUX_CONFIG_ENET,
+       MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MUX_CONFIG_ENET,
+       MX28_PAD_ENET_CLK__CLKCTRL_ENET | MUX_CONFIG_ENET,
+
+       /* MMC pads */
+       MX28_PAD_SSP0_DATA0__SSP0_D0 | MUX_CONFIG_SSP0,
+       MX28_PAD_SSP0_DATA1__SSP0_D1 | MUX_CONFIG_SSP0,
+       MX28_PAD_SSP0_DATA2__SSP0_D2 | MUX_CONFIG_SSP0,
+       MX28_PAD_SSP0_DATA3__SSP0_D3 | MUX_CONFIG_SSP0,
+       MX28_PAD_SSP0_CMD__SSP0_CMD | MUX_CONFIG_SSP0,
+       MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT | MUX_CONFIG_GPIO,
+       MX28_PAD_SSP0_SCK__SSP0_SCK | MUX_CONFIG_SSP0,
+
+       /* GPMI pads */
+       MX28_PAD_GPMI_D00__GPMI_D0 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_D01__GPMI_D1 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_D02__GPMI_D2 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_D03__GPMI_D3 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_D04__GPMI_D4 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_D05__GPMI_D5 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_D06__GPMI_D6 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_D07__GPMI_D7 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_CE0N__GPMI_CE0N | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_RDY0__GPMI_READY0 | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_RDN__GPMI_RDN | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_WRN__GPMI_WRN | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_ALE__GPMI_ALE | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_CLE__GPMI_CLE | MUX_CONFIG_GPMI,
+       MX28_PAD_GPMI_RESETN__GPMI_RESETN | MUX_CONFIG_GPMI,
+
+       /* maybe used for EDT-FT5x06 */
+       MX28_PAD_SSP0_DATA5__GPIO_2_5 | MUX_CONFIG_GPIO,
+       MX28_PAD_SSP0_DATA6__GPIO_2_6 | MUX_CONFIG_GPIO,
+       MX28_PAD_ENET0_RXD2__GPIO_4_9 | MUX_CONFIG_GPIO,
+
+       /* unused pads */
+       MX28_PAD_GPMI_RDY1__GPIO_0_21 | MUX_CONFIG_GPIO,
+       MX28_PAD_GPMI_RDY2__GPIO_0_22 | MUX_CONFIG_GPIO,
+       MX28_PAD_GPMI_RDY3__GPIO_0_23 | MUX_CONFIG_GPIO,
+       MX28_PAD_GPMI_CE1N__GPIO_0_17 | MUX_CONFIG_GPIO,
+       MX28_PAD_GPMI_CE2N__GPIO_0_18 | MUX_CONFIG_GPIO,
+       MX28_PAD_GPMI_CE3N__GPIO_0_19 | MUX_CONFIG_GPIO,
+
+       MX28_PAD_SSP0_DATA4__GPIO_2_4 | MUX_CONFIG_GPIO,
+       MX28_PAD_SSP0_DATA7__GPIO_2_7 | MUX_CONFIG_GPIO,
+
+       MX28_PAD_SSP2_SS0__GPIO_2_19 | MUX_CONFIG_GPIO,
+       MX28_PAD_SSP2_SS1__GPIO_2_20 | MUX_CONFIG_GPIO,
+       MX28_PAD_SSP2_SS2__GPIO_2_21 | MUX_CONFIG_GPIO,
+       MX28_PAD_SSP3_SS0__GPIO_2_27 | MUX_CONFIG_GPIO,
+
+       MX28_PAD_ENET0_TXD2__GPIO_4_11 | MUX_CONFIG_GPIO,
+       MX28_PAD_ENET0_TXD3__GPIO_4_12 | MUX_CONFIG_GPIO,
+       MX28_PAD_ENET0_CRS__GPIO_4_15 | MUX_CONFIG_GPIO,
+};
+
+static void tx28_stk5_lcd_init(void)
+{
+       gpio_direction_output(MX28_PAD_PWM0__GPIO_3_16, 1);
+       gpio_direction_output(MX28_PAD_LCD_RESET__GPIO_3_30, 0);
+       gpio_direction_output(MX28_PAD_LCD_ENABLE__GPIO_1_31, 0);
+}
+
+static void tx28_stk5_led_on(void)
+{
+       gpio_direction_output(MX28_PAD_ENET0_RXD3__GPIO_4_10, 1);
+}
+
+void board_init_ll(void)
+{
+       mxs_common_spl_init(tx28_stk5_pads, ARRAY_SIZE(tx28_stk5_pads));
+       tx28_stk5_lcd_init();
+       tx28_stk5_led_on();
+}
+
+static uint32_t tx28_dram_vals[] = {
+#ifdef CONFIG_TX28_S
+       /* TX28-41x0: NT5TU32M16DG-AC */
+       /* 000 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 010 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 020 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 030 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 040 */ 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+       /* 050 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 060 */ 0x00000000, 0x00000000, 0x00010101, 0x00010101,
+       /* 070 */ 0x000f0f01, 0x0102010a, 0x00000000, 0x00000101,
+       /* 080 */ 0x00000100, 0x00000100, 0x00000000, 0x00000002,
+       /* 090 */ 0x01010000, 0x07080403, 0x06005003, 0x0a0000c8,
+       /* 0a0 */ 0x02009c40, 0x0002030c, 0x0036a609, 0x031a0612,
+       /* 0b0 */ 0x02030202, 0x00c8001c, 0x00000000, 0x00000000,
+       /* 0c0 */ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+       /* 0d0 */ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+       /* 0e0 */ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       /* 0f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 100 */ 0x00000000, 0x00000000, 0x00000612, 0x01000f02,
+       /* 110 */ 0x06120612, 0x00000200, 0x00020007, 0xf4004a27,
+       /* 120 */ 0xf4004a27, 0xf4004a27, 0xf4004a27, 0x07400300,
+       /* 130 */ 0x07400300, 0x07400300, 0x07400300, 0x00000005,
+       /* 140 */ 0x00000000, 0x00000000, 0x01000000, 0x01020408,
+       /* 150 */ 0x08040201, 0x000f1133, 0x00000000, 0x00001f04,
+       /* 160 */ 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
+       /* 170 */ 0x00001f04, 0x00001f04, 0x00001f04, 0x00000000,
+       /* 180 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 190 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 200 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 210 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 220 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 230 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 240 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 250 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 260 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 270 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 280 */ 0x00000000, 0x00000000, 0x00010000, 0x00030404,
+       /* 290 */ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       /* 2a0 */ 0x00000000, 0x00000000, 0x00000000, 0x01010000,
+       /* 2b0 */ 0x01000000, 0x03030000, 0x00010303, 0x01020202,
+       /* 2c0 */ 0x00000000, 0x02040303, 0x21002103, 0x00061200,
+       /* 2d0 */ 0x06120612, 0x04420442, 0x04420442, 0x00040004,
+       /* 2e0 */ 0x00040004, 0x00000000, 0x00000000, 0x00000000,
+       /* 2f0 */ 0x00000000, 0x00000000,
+#elif CONFIG_SDRAM_SIZE == SZ_128M
+       /* TX28-40x0: MT47H64M16HR-3 */
+       /* 000 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 010 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 020 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 030 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 040 */ 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+       /* 050 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 060 */ 0x00000000, 0x00000000, 0x00010101, 0x01010101,
+       /* 070 */ 0x000f0f01, 0x0102020a, 0x00000000, 0x00010101,
+       /* 080 */ 0x00000100, 0x00000100, 0x00000000, 0x00000002,
+       /* 090 */ 0x01010000, 0x07080403, 0x06005003, 0x0a0000c8,
+       /* 0a0 */ 0x02009c40, 0x0002030c, 0x0036a609, 0x031a0612,
+       /* 0b0 */ 0x02030202, 0x00c8001c, 0x00000000, 0x00000000,
+       /* 0c0 */ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+       /* 0d0 */ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+       /* 0e0 */ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       /* 0f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 100 */ 0x00000000, 0x00000000, 0x00000612, 0x01000f02,
+       /* 110 */ 0x06120612, 0x00000200, 0x00020007, 0xf4004a27,
+       /* 120 */ 0xf4004a27, 0xf4004a27, 0xf4004a27, 0x07400300,
+       /* 130 */ 0x07400300, 0x07400300, 0x07400300, 0x00000005,
+       /* 140 */ 0x00000000, 0x00000000, 0x01000000, 0x01020408,
+       /* 150 */ 0x08040201, 0x000f1133, 0x00000000, 0x00001f04,
+       /* 160 */ 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
+       /* 170 */ 0x00001f04, 0x00001f04, 0x00001f04, 0x00000000,
+       /* 180 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 190 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 200 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 210 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 220 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 230 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 240 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 250 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 260 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 270 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 280 */ 0x00000000, 0x00000000, 0x00010000, 0x00030404,
+       /* 290 */ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       /* 2a0 */ 0x00000000, 0x00000000, 0x00000000, 0x01010000,
+       /* 2b0 */ 0x01000000, 0x03030000, 0x00010303, 0x01020202,
+       /* 2c0 */ 0x00000000, 0x02040303, 0x21002103, 0x00061200,
+       /* 2d0 */ 0x06120612, 0x04420442, 0x04420442, 0x00040004,
+       /* 2e0 */ 0x00040004, 0x00000000, 0x00000000, 0x00000000,
+       /* 2f0 */ 0x00000000, 0x00000000,
+#elif CONFIG_SDRAM_SIZE == SZ_256M
+       /* TX28-40x2: MEM2G16D2DABG */
+       /* 000 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 010 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 020 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 030 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 040 */ 0x00000000, 0x00000100, 0x00000000, 0x00000000,
+       /* 050 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 060 */ 0x00000000, 0x00000000, 0x00010101, 0x01010101,
+       /* 070 */ 0x000f0f01, 0x0102010a, 0x00000000, 0x00010101,
+       /* 080 */ 0x00000100, 0x00000100, 0x00000000, 0x00000002,
+       /* 090 */ 0x01010000, 0x07080603, 0x07005003, 0x0a0000c8,
+       /* 0a0 */ 0x02009c40, 0x0002030c, 0x00380e09, 0x0328063f,
+       /* 0b0 */ 0x02030202, 0x00c8001c, 0x00000000, 0x00000000,
+       /* 0c0 */ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+       /* 0d0 */ 0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
+       /* 0e0 */ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       /* 0f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 100 */ 0x00000000, 0x00000000, 0x00000612, 0x01000102,
+       /* 110 */ 0x06120612, 0x00000200, 0x00020007, 0xf4002714,
+       /* 120 */ 0xf4002714, 0xf4002714, 0xf4002714, 0x07400300,
+       /* 130 */ 0x07400300, 0x07400300, 0x07400300, 0x00000005,
+       /* 140 */ 0x00000000, 0x00000000, 0x01000000, 0x01020408,
+       /* 150 */ 0x08040201, 0x000f1133, 0x00000000, 0x00001f04,
+       /* 160 */ 0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
+       /* 170 */ 0x00001f04, 0x00001f04, 0x00001f04, 0x00000000,
+       /* 180 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 190 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1a0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1b0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1c0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1d0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1e0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 1f0 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 200 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 210 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 220 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 230 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 240 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 250 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 260 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 270 */ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+       /* 280 */ 0x00000000, 0x00000000, 0x00010000, 0x00030404,
+       /* 290 */ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
+       /* 2a0 */ 0x00000000, 0x00000000, 0x00000000, 0x01010000,
+       /* 2b0 */ 0x01000000, 0x03030000, 0x00010303, 0x01020202,
+       /* 2c0 */ 0x00000000, 0x02040303, 0x21002103, 0x00061200,
+       /* 2d0 */ 0x06120612, 0x04420442, 0x04420442, 0x00040004,
+       /* 2e0 */ 0x00040004, 0x00000000, 0x00000000, 0x00000000,
+       /* 2f0 */ 0x00000000, 0x00000000,
+#else
+#error No SDRAM configuration available
+#endif
+};
+
+void mxs_adjust_memory_params(uint32_t *dram_vals)
+{
+       memcpy(dram_vals, tx28_dram_vals, sizeof(tx28_dram_vals));
+}
diff --git a/board/karo/tx28/tx28.c b/board/karo/tx28/tx28.c
new file mode 100644 (file)
index 0000000..c578c06
--- /dev/null
@@ -0,0 +1,1018 @@
+/*
+ * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
+ * based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <lcd.h>
+#include <netdev.h>
+#include <mmc.h>
+#include <mxcfb.h>
+#include <linux/list.h>
+#include <linux/fb.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/iomux-mx28.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+
+#include "../common/karo.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MXS_GPIO_NR(p, o)      (((p) << 5) | (o))
+
+#define TX28_LCD_PWR_GPIO      MX28_PAD_LCD_ENABLE__GPIO_1_31
+#define TX28_LCD_RST_GPIO      MX28_PAD_LCD_RESET__GPIO_3_30
+#define TX28_LCD_BACKLIGHT_GPIO        MX28_PAD_PWM0__GPIO_3_16
+
+#define TX28_USBH_VBUSEN_GPIO  MX28_PAD_SPDIF__GPIO_3_27
+#define TX28_USBH_OC_GPIO      MX28_PAD_JTAG_RTCK__GPIO_4_20
+#define TX28_USBOTG_VBUSEN_GPIO        MX28_PAD_GPMI_CE2N__GPIO_0_18
+#define TX28_USBOTG_OC_GPIO    MX28_PAD_GPMI_CE3N__GPIO_0_19
+#define TX28_USBOTG_ID_GPIO    MX28_PAD_PWM2__GPIO_3_18
+
+#define TX28_LED_GPIO          MX28_PAD_ENET0_RXD3__GPIO_4_10
+
+#define STK5_CAN_XCVR_GPIO     MX28_PAD_LCD_D00__GPIO_1_0
+
+static const struct gpio tx28_gpios[] = {
+       { TX28_USBH_VBUSEN_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "USBH VBUSEN", },
+       { TX28_USBH_OC_GPIO, GPIOFLAG_INPUT, "USBH OC", },
+       { TX28_USBOTG_VBUSEN_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "USBOTG VBUSEN", },
+       { TX28_USBOTG_OC_GPIO, GPIOFLAG_INPUT, "USBOTG OC", },
+       { TX28_USBOTG_ID_GPIO, GPIOFLAG_INPUT, "USBOTG ID", },
+};
+
+static const iomux_cfg_t tx28_pads[] = {
+       /* UART pads */
+#if CONFIG_CONS_INDEX == 0
+       MX28_PAD_AUART0_RX__DUART_CTS,
+       MX28_PAD_AUART0_TX__DUART_RTS,
+       MX28_PAD_AUART0_CTS__DUART_RX,
+       MX28_PAD_AUART0_RTS__DUART_TX,
+#elif CONFIG_CONS_INDEX == 1
+       MX28_PAD_AUART1_RX__AUART1_RX,
+       MX28_PAD_AUART1_TX__AUART1_TX,
+       MX28_PAD_AUART1_CTS__AUART1_CTS,
+       MX28_PAD_AUART1_RTS__AUART1_RTS,
+#elif CONFIG_CONS_INDEX == 2
+       MX28_PAD_AUART3_RX__AUART3_RX,
+       MX28_PAD_AUART3_TX__AUART3_TX,
+       MX28_PAD_AUART3_CTS__AUART3_CTS,
+       MX28_PAD_AUART3_RTS__AUART3_RTS,
+#endif
+       /* I2C bus for internal DS1339, PCA9554 and on DIMM pins 40/41 */
+       MX28_PAD_I2C0_SCL__I2C0_SCL,
+       MX28_PAD_I2C0_SDA__I2C0_SDA,
+
+       /* USBH VBUSEN, OC */
+       MX28_PAD_SPDIF__GPIO_3_27,
+       MX28_PAD_JTAG_RTCK__GPIO_4_20,
+
+       /* USBOTG VBUSEN, OC, ID */
+       MX28_PAD_GPMI_CE2N__GPIO_0_18,
+       MX28_PAD_GPMI_CE3N__GPIO_0_19,
+       MX28_PAD_PWM2__GPIO_3_18,
+};
+
+/*
+ * Functions
+ */
+
+/* provide at least _some_ sort of randomness */
+#define MAX_LOOPS       100
+
+static u32 random;
+
+static inline void random_init(void)
+{
+       struct mxs_digctl_regs *digctl_regs = (void *)MXS_DIGCTL_BASE;
+       u32 seed = 0;
+       int i;
+
+       for (i = 0; i < MAX_LOOPS; i++) {
+               u32 hclk = readl(&digctl_regs->hw_digctl_hclkcount);
+               u32 entropy = readl(&digctl_regs->hw_digctl_entropy);
+               u32 usec = readl(&digctl_regs->hw_digctl_microseconds);
+
+               seed = get_timer(hclk ^ entropy ^ usec ^ random ^ seed);
+               srand(seed);
+               random = rand();
+       }
+}
+
+#define RTC_PERSISTENT0_CLK32_MASK     (RTC_PERSISTENT0_CLOCKSOURCE |  \
+                                       RTC_PERSISTENT0_XTAL32KHZ_PWRUP)
+static u32 boot_cause __attribute__((section("data")));
+
+int board_early_init_f(void)
+{
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
+       u32 rtc_stat;
+       int timeout = 5000;
+
+       random_init();
+
+       /* IO0 clock at 480MHz */
+       mxs_set_ioclk(MXC_IOCLK0, 480000);
+       /* IO1 clock at 480MHz */
+       mxs_set_ioclk(MXC_IOCLK1, 480000);
+
+       /* SSP0 clock at 96MHz */
+       mxs_set_sspclk(MXC_SSPCLK0, 96000, 0);
+       /* SSP2 clock at 96MHz */
+       mxs_set_sspclk(MXC_SSPCLK2, 96000, 0);
+
+       gpio_request_array(tx28_gpios, ARRAY_SIZE(tx28_gpios));
+       mxs_iomux_setup_multiple_pads(tx28_pads, ARRAY_SIZE(tx28_pads));
+
+       while ((rtc_stat = readl(&rtc_regs->hw_rtc_stat)) &
+               RTC_STAT_STALE_REGS_PERSISTENT0) {
+               if (timeout-- < 0)
+                       return 1;
+               udelay(1);
+       }
+       boot_cause = readl(&rtc_regs->hw_rtc_persistent0);
+       if ((boot_cause & RTC_PERSISTENT0_CLK32_MASK) !=
+               RTC_PERSISTENT0_CLK32_MASK) {
+               if (boot_cause & RTC_PERSISTENT0_CLOCKSOURCE)
+                       goto rtc_err;
+               writel(RTC_PERSISTENT0_CLK32_MASK,
+                       &rtc_regs->hw_rtc_persistent0_set);
+       }
+       return 0;
+
+rtc_err:
+       serial_puts("Inconsistent value in RTC_PERSISTENT0 register; power-on-reset required\n");
+       return 1;
+}
+
+int board_init(void)
+{
+       if (ctrlc()) {
+               printf("CTRL-C detected; safeboot enabled\n");
+               return 1;
+       }
+
+       /* Address of boot parameters */
+#ifdef CONFIG_OF_LIBFDT
+       gd->bd->bi_arch_number = -1;
+#endif
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
+       return 0;
+}
+
+int dram_init(void)
+{
+       return mxs_dram_init();
+}
+
+#ifdef CONFIG_CMD_MMC
+static int tx28_mmc_wp(int dev_no)
+{
+       return 0;
+}
+
+int board_mmc_init(bd_t *bis)
+{
+       return mxsmmc_initialize(bis, 0, tx28_mmc_wp, NULL);
+}
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_FEC_MXC
+#ifdef CONFIG_GET_FEC_MAC_ADDR_FROM_IIM
+
+#ifdef CONFIG_FEC_MXC_MULTI
+#define FEC_MAX_IDX                    1
+#else
+#define FEC_MAX_IDX                    0
+#endif
+#ifndef ETH_ALEN
+#define ETH_ALEN                       6
+#endif
+
+static int fec_get_mac_addr(int index)
+{
+       int timeout = 1000;
+       struct mxs_ocotp_regs *ocotp_regs =
+               (struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
+       u32 *cust = &ocotp_regs->hw_ocotp_cust0;
+       u8 mac[ETH_ALEN];
+       char env_name[] = "eth.addr";
+       u32 val = 0;
+       int i;
+
+       if (index < 0 || index > FEC_MAX_IDX)
+               return -EINVAL;
+
+       /* set this bit to open the OTP banks for reading */
+       writel(OCOTP_CTRL_RD_BANK_OPEN,
+               &ocotp_regs->hw_ocotp_ctrl_set);
+
+       /* wait until OTP contents are readable */
+       while (OCOTP_CTRL_BUSY & readl(&ocotp_regs->hw_ocotp_ctrl)) {
+               if (timeout-- < 0)
+                       return -ETIMEDOUT;
+               udelay(100);
+       }
+
+       for (i = 0; i < sizeof(mac); i++) {
+               int shift = 24 - i % 4 * 8;
+
+               if (i % 4 == 0)
+                       val = readl(&cust[index * 8 + i]);
+               mac[i] = val >> shift;
+       }
+       if (!is_valid_ether_addr(mac)) {
+               if (index == 0)
+                       printf("No valid MAC address programmed\n");
+               return 0;
+       }
+
+       if (index == 0) {
+               printf("MAC addr from fuse: %pM\n", mac);
+               snprintf(env_name, sizeof(env_name), "ethaddr");
+       } else {
+               snprintf(env_name, sizeof(env_name), "eth%daddr", index);
+       }
+       eth_setenv_enetaddr(env_name, mac);
+       return 0;
+}
+#endif /* CONFIG_GET_FEC_MAC_ADDR_FROM_IIM */
+
+static const iomux_cfg_t tx28_fec_pads[] = {
+       MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
+       MX28_PAD_ENET0_RXD0__ENET0_RXD0,
+       MX28_PAD_ENET0_RXD1__ENET0_RXD1,
+};
+
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       /* Reset the external phy */
+       gpio_direction_output(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 0);
+
+       /* Power on the external phy */
+       gpio_direction_output(MX28_PAD_PWM4__GPIO_3_29, 1);
+
+       /* Pull strap pins to high */
+       gpio_direction_output(MX28_PAD_ENET0_RX_EN__GPIO_4_2, 1);
+       gpio_direction_output(MX28_PAD_ENET0_RXD0__GPIO_4_3, 1);
+       gpio_direction_output(MX28_PAD_ENET0_RXD1__GPIO_4_4, 1);
+       gpio_direction_input(MX28_PAD_ENET0_TX_CLK__GPIO_4_5);
+
+       udelay(25000);
+       gpio_set_value(MX28_PAD_ENET0_RX_CLK__GPIO_4_13, 1);
+       udelay(100);
+
+       mxs_iomux_setup_multiple_pads(tx28_fec_pads, ARRAY_SIZE(tx28_fec_pads));
+
+       ret = cpu_eth_init(bis);
+       if (ret) {
+               printf("cpu_eth_init() failed: %d\n", ret);
+               return ret;
+       }
+
+#ifdef CONFIG_FEC_MXC_MULTI
+       if (getenv("ethaddr")) {
+               ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
+               if (ret) {
+                       printf("FEC MXS: Unable to init FEC0\n");
+                       return ret;
+               }
+       }
+
+       if (getenv("eth1addr")) {
+               ret = fecmxc_initialize_multi(bis, 1, 1, MXS_ENET1_BASE);
+               if (ret) {
+                       printf("FEC MXS: Unable to init FEC1\n");
+                       return ret;
+               }
+       }
+#else
+       if (getenv("ethaddr")) {
+               ret = fecmxc_initialize(bis);
+               if (ret) {
+                       printf("FEC MXS: Unable to init FEC\n");
+                       return ret;
+               }
+       }
+#endif
+       return 0;
+}
+#endif /* CONFIG_FEC_MXC */
+
+enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+};
+
+void show_activity(int arg)
+{
+       static int led_state = LED_STATE_INIT;
+       static ulong last;
+
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX28_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+       } else {
+               if (get_timer(last) > CONFIG_SYS_HZ) {
+                       last = get_timer(0);
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX28_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX28_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+}
+
+static const iomux_cfg_t stk5_pads[] = {
+       /* SW controlled LED on STK5 baseboard */
+       MX28_PAD_ENET0_RXD3__GPIO_4_10,
+};
+
+static const struct gpio stk5_gpios[] = {
+};
+
+#ifdef CONFIG_LCD
+static ushort tx28_cmap[256];
+vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1600,
+       .vl_row = 1200,
+
+       .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx28_cmap,
+};
+
+static struct fb_videomode tx28_fb_modes[] = {
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .vmode          = FB_VMODE_NONINTERLACED,
+       },
+};
+
+static int lcd_enabled = 1;
+static int lcd_bl_polarity;
+
+static int lcd_backlight_polarity(void)
+{
+       return lcd_bl_polarity;
+}
+
+void lcd_enable(void)
+{
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+
+       karo_load_splashimage(1);
+       if (lcd_enabled) {
+               debug("Switching LCD on\n");
+               gpio_set_value(TX28_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX28_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX28_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+}
+
+void lcd_disable(void)
+{
+}
+
+void lcd_panel_disable(void)
+{
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX28_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX28_LCD_RST_GPIO, 0);
+               gpio_set_value(TX28_LCD_PWR_GPIO, 0);
+       }
+}
+
+static const iomux_cfg_t stk5_lcd_pads[] = {
+       /* LCD RESET */
+       MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL,
+       /* LCD POWER_ENABLE */
+       MX28_PAD_LCD_ENABLE__GPIO_1_31 | MXS_PAD_CTRL,
+       /* LCD Backlight (PWM) */
+       MX28_PAD_PWM0__GPIO_3_16 | MXS_PAD_CTRL,
+
+       /* Display */
+       MX28_PAD_LCD_D00__LCD_D0 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D01__LCD_D1 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D02__LCD_D2 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D03__LCD_D3 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D04__LCD_D4 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D05__LCD_D5 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D06__LCD_D6 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D07__LCD_D7 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D08__LCD_D8 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D09__LCD_D9 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D10__LCD_D10 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D11__LCD_D11 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D12__LCD_D12 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D13__LCD_D13 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D14__LCD_D14 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D15__LCD_D15 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D16__LCD_D16 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D17__LCD_D17 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D18__LCD_D18 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D19__LCD_D19 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D20__LCD_D20 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D21__LCD_D21 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D22__LCD_D22 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_D23__LCD_D23 | MXS_PAD_CTRL,
+       MX28_PAD_LCD_RD_E__LCD_VSYNC | MXS_PAD_CTRL,
+       MX28_PAD_LCD_WR_RWN__LCD_HSYNC | MXS_PAD_CTRL,
+       MX28_PAD_LCD_RS__LCD_DOTCLK | MXS_PAD_CTRL,
+       MX28_PAD_LCD_CS__LCD_CS | MXS_PAD_CTRL,
+};
+
+static const struct gpio stk5_lcd_gpios[] = {
+       { TX28_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
+       { TX28_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
+       { TX28_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+};
+
+extern void video_hw_init(void *lcdbase);
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = tx28_fb_modes;
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+
+       if (had_ctrlc()) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+
+       karo_fdt_move_fdt();
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 8:
+                                       case 16:
+                                       case 18:
+                                       case 24:
+                                               color_depth = val;
+                                               break;
+
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx28_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
+               panel_info.vl_bpix = LCD_COLOR32;
+       }
+
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
+                               1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000);
+
+       if (p != &fb_mode) {
+               int ret;
+
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       mxs_iomux_setup_multiple_pads(stk5_lcd_pads,
+                               ARRAY_SIZE(stk5_lcd_pads));
+
+       debug("video format: %ux%u-%u@%u\n", p->xres, p->yres,
+               color_depth, refresh);
+
+       if (karo_load_splashimage(0) == 0) {
+               char vmode[128];
+
+               /* setup env variable for mxsfb display driver */
+               snprintf(vmode, sizeof(vmode),
+                       "x:%d,y:%d,le:%d,ri:%d,up:%d,lo:%d,hs:%d,vs:%d,sync:%d,pclk:%d,depth:%d",
+                       p->xres, p->yres, p->left_margin, p->right_margin,
+                       p->upper_margin, p->lower_margin, p->hsync_len,
+                       p->vsync_len, p->sync, p->pixclock, color_depth);
+               setenv("videomode", vmode);
+
+               debug("Initializing LCD controller\n");
+               video_hw_init(lcdbase);
+               setenv("videomode", NULL);
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+}
+#else
+#define lcd_enabled 0
+#endif /* CONFIG_LCD */
+
+static void stk5_board_init(void)
+{
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       mxs_iomux_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+}
+
+static void stk5v3_board_init(void)
+{
+       stk5_board_init();
+}
+
+static void stk5v5_board_init(void)
+{
+       stk5_board_init();
+
+       /* init flexcan transceiver enable GPIO */
+       gpio_request_one(STK5_CAN_XCVR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH,
+                       "Flexcan Transceiver");
+       SETUP_IOMUX_PAD(STK5_CAN_XCVR_GPIO);
+}
+
+int tx28_fec1_enabled(void)
+{
+       const char *status;
+       int off;
+
+       if (!gd->fdt_blob)
+               return 0;
+
+       off = fdt_path_offset(gd->fdt_blob, "ethernet1");
+       if (off < 0)
+               return 0;
+
+       status = fdt_getprop(gd->fdt_blob, off, "status", NULL);
+       return status && (strcmp(status, "okay") == 0);
+}
+
+static void tx28_init_mac(void)
+{
+       int ret;
+
+       ret = fec_get_mac_addr(0);
+       if (ret < 0) {
+               printf("Failed to read FEC0 MAC address from OCOTP\n");
+               return;
+       }
+#ifdef CONFIG_FEC_MXC_MULTI
+       if (tx28_fec1_enabled()) {
+               ret = fec_get_mac_addr(1);
+               if (ret < 0) {
+                       printf("Failed to read FEC1 MAC address from OCOTP\n");
+                       return;
+               }
+       }
+#endif
+}
+
+int board_late_init(void)
+{
+       int ret = 0;
+       const char *baseboard;
+
+       env_cleanup();
+
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else
+               karo_fdt_move_fdt();
+
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+
+       printf("Baseboard: %s\n", baseboard);
+
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       const char *otg_mode = getenv("otg_mode");
+
+                       if (otg_mode && strcmp(otg_mode, "host") == 0) {
+                               printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
+                                       otg_mode, baseboard);
+                               setenv("otg_mode", "none");
+                       }
+                       stk5v5_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+
+exit:
+       tx28_init_mac();
+       clear_ctrlc();
+       return ret;
+}
+
+#define BOOT_CAUSE_MASK                (RTC_PERSISTENT0_EXTERNAL_RESET |       \
+                               RTC_PERSISTENT0_ALARM_WAKE |            \
+                               RTC_PERSISTENT0_THERMAL_RESET)
+
+static void thermal_init(void)
+{
+       struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
+       struct mxs_clkctrl_regs *clkctrl_regs = (void *)MXS_CLKCTRL_BASE;
+
+       writel(POWER_THERMAL_LOW_POWER | POWER_THERMAL_OFFSET_ADJ_ENABLE |
+               POWER_THERMAL_OFFSET_ADJ_OFFSET(3),
+               &power_regs->hw_power_thermal);
+
+       writel(CLKCTRL_RESET_EXTERNAL_RESET_ENABLE |
+               CLKCTRL_RESET_THERMAL_RESET_ENABLE,
+               &clkctrl_regs->hw_clkctrl_reset);
+}
+
+int checkboard(void)
+{
+       struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
+       u32 pwr_sts = readl(&power_regs->hw_power_sts);
+       u32 pwrup_src = (pwr_sts >> 24) & 0x3f;
+       const char *dlm = "";
+
+       printf("Board: Ka-Ro TX28-4%sx%d\n", TX28_MOD_SUFFIX,
+               CONFIG_SDRAM_SIZE / SZ_128M +
+               CONFIG_SYS_NAND_BLOCKS / 2048 * 2);
+
+       printf("POWERUP Source: ");
+       if (pwrup_src & (3 << 0)) {
+               printf("%sPSWITCH %s voltage", dlm,
+                       pwrup_src & (1 << 1) ? "HIGH" : "MID");
+               dlm = " | ";
+       }
+       if (pwrup_src & (1 << 4)) {
+               printf("%sRTC", dlm);
+               dlm = " | ";
+       }
+       if (pwrup_src & (1 << 5)) {
+               printf("%s5V", dlm);
+               dlm = " | ";
+       }
+       printf("\n");
+
+       if (boot_cause & BOOT_CAUSE_MASK) {
+               dlm="";
+               printf("Last boot cause: ");
+               if (boot_cause & RTC_PERSISTENT0_EXTERNAL_RESET) {
+                       printf("%sEXTERNAL", dlm);
+                       dlm = " | ";
+               }
+               if (boot_cause & RTC_PERSISTENT0_THERMAL_RESET) {
+                       printf("%sTHERMAL", dlm);
+                       dlm = " | ";
+               }
+               if (*dlm != '\0')
+                       printf(" RESET");
+               if (boot_cause & RTC_PERSISTENT0_ALARM_WAKE) {
+                       printf("%sALARM WAKE", dlm);
+                       dlm = " | ";
+               }
+               printf("\n");
+       }
+
+       while (pwr_sts & POWER_STS_THERMAL_WARNING) {
+               static int first = 1;
+
+               if (first) {
+                       printf("CPU too hot to boot\n");
+                       first = 0;
+               }
+               if (tstc())
+                       break;
+               pwr_sts = readl(&power_regs->hw_power_sts);
+       }
+
+       if (!(boot_cause & RTC_PERSISTENT0_THERMAL_RESET))
+               thermal_init();
+
+       return 0;
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+#ifdef CONFIG_FDT_FIXUP_PARTITIONS
+#include <jffs2/jffs2.h>
+#include <mtd_node.h>
+static struct node_info tx28_nand_nodes[] = {
+       { "fsl,imx28-gpmi-nand", MTD_DEV_TYPE_NAND, },
+};
+#else
+#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+#endif
+
+static const char *tx28_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "fsl,imx28-lradc",
+};
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+
+       ret = fdt_increase_size(blob, 4096);
+       if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
+               return ret;
+       }
+#ifdef CONFIG_TX28_S
+       /* TX28-41xx (aka TX28S) has no external RTC
+        * and no I2C GPIO extender
+        */
+       karo_fdt_remove_node(blob, "ds1339");
+       karo_fdt_remove_node(blob, "gpio5");
+#endif
+       if (stk5_v5)
+               karo_fdt_enable_node(blob, "stk5led", 0);
+
+       fdt_fixup_mtdparts(blob, tx28_nand_nodes, ARRAY_SIZE(tx28_nand_nodes));
+       fdt_fixup_ethernet(blob);
+
+       karo_fdt_fixup_touchpanel(blob, tx28_touchpanels,
+                               ARRAY_SIZE(tx28_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+       karo_fdt_update_fb_mode(blob, video_mode);
+
+       return 0;
+}
+#endif /* CONFIG_OF_BOARD_SETUP */
diff --git a/board/karo/tx28/u-boot.bd b/board/karo/tx28/u-boot.bd
new file mode 100644 (file)
index 0000000..bbf6658
--- /dev/null
@@ -0,0 +1,14 @@
+sources {
+       u_boot_spl="@@BUILD_DIR@@spl/u-boot-spl";
+       u_boot="@@BUILD_DIR@@u-boot";
+}
+
+section (0) {
+       load u_boot_spl;
+       load ivt (entry = u_boot_spl:reset) > 0x8000;
+       hab call 0x8000;
+
+       load u_boot;
+       load ivt (entry = u_boot:reset) > 0x8000;
+       hab call 0x8000;
+}
diff --git a/board/karo/tx48/Kconfig b/board/karo/tx48/Kconfig
new file mode 100644 (file)
index 0000000..ea17d4c
--- /dev/null
@@ -0,0 +1,15 @@
+if TARGET_TX48
+
+config SYS_BOARD
+       default "tx48"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "am33xx"
+
+config SYS_CONFIG_NAME
+       default "tx48"
+
+endif
diff --git a/board/karo/tx48/Makefile b/board/karo/tx48/Makefile
new file mode 100644 (file)
index 0000000..405e8ca
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+ifneq ($(CONFIG_SPL_BUILD),y)
+       obj-y                   += tx48.o
+else
+       obj-y                   += spl.o
+endif
diff --git a/board/karo/tx48/config.mk b/board/karo/tx48/config.mk
new file mode 100644 (file)
index 0000000..51490f0
--- /dev/null
@@ -0,0 +1,7 @@
+CONFIG_SYS_TEXT_BASE = 0x80800000
+ifneq ($(CONFIG_SPL_BUILD),)
+       CONFIG_SPL_TEXT_BASE = 0x402F0400
+endif
+PLATFORM_CPPFLAGS += -Werror
+
+LOGO_BMP = logos/karo.bmp
diff --git a/board/karo/tx48/flash.h b/board/karo/tx48/flash.h
new file mode 100644 (file)
index 0000000..bc587c5
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2013 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* timing parameters for Samsung K9F1G08U0D */
+#define tCS_NAND               20
+#define tCH_NAND               5
+#define tCEA_NAND              25
+#define tREA_NAND              20
+#define tWP_NAND               15
+#define tRP_NAND               15
+#define tWC_NAND               30
+#define tRC_NAND               30
+#define tALS_NAND              15
+#define tADL_NAND              100
+#define tRHW_NAND              100
+
+/* Values for GPMC_CONFIG1 - signal control parameters */
+#define WRAPBURST                      (1 << 31)
+#define READMULTIPLE                   (1 << 30)
+#define READTYPE                       (1 << 29)
+#define WRITEMULTIPLE                  (1 << 28)
+#define WRITETYPE                      (1 << 27)
+#define CLKACTIVATIONTIME(x)           (((x) & 3) << 25)
+#define ATTACHEDDEVICEPAGELENGTH(x)    (((x) & 3) << 23)
+#define WAITREADMONITORING             (1 << 22)
+#define WAITWRITEMONITORING            (1 << 21)
+#define WAITMONITORINGTIME(x)          (((x) & 3) << 18)
+#define WAITPINSELECT(x)               (((x) & 3) << 16)
+#define DEVICESIZE(x)                  (((x) & 3) << 12)
+#define DEVICESIZE_8BIT                        DEVICESIZE(0)
+#define DEVICESIZE_16BIT               DEVICESIZE(1)
+#define DEVICETYPE(x)                  (((x) & 3) << 10)
+#define DEVICETYPE_NOR                 DEVICETYPE(0)
+#define DEVICETYPE_NAND                        DEVICETYPE(2)
+#define MUXADDDATA(n)                  ((n) << 8)
+#define TIMEPARAGRANULARITY            (1 << 4)
+#define GPMCFCLKDIVIDER(x)             (((x) & 3) << 0)
+
+/* Values for GPMC_CONFIG2 - CS timing */
+#define CSWROFFTIME(x)                 (((x) & 0x1f) << 16)
+#define CSRDOFFTIME(x)                 (((x) & 0x1f) <<  8)
+#define CSEXTRADELAY                   (1 << 7)
+#define CSONTIME(x)                    (((x) &  0xf) <<  0)
+
+/* Values for GPMC_CONFIG3 - nADV timing */
+#define ADVWROFFTIME(x)                        (((x) & 0x1f) << 16)
+#define ADVRDOFFTIME(x)                        (((x) & 0x1f) <<  8)
+#define ADVEXTRADELAY                  (1 << 7)
+#define ADVONTIME(x)                   (((x) &  0xf) <<  0)
+
+/* Values for GPMC_CONFIG4 - nWE and nOE timing */
+#define WEOFFTIME(x)                   (((x) & 0x1f) << 24)
+#define WEEXTRADELAY                   (1 << 23)
+#define WEONTIME(x)                    (((x) &  0xf) << 16)
+#define OEOFFTIME(x)                   (((x) & 0x1f) <<  8)
+#define OEEXTRADELAY                   (1 << 7)
+#define OEONTIME(x)                    (((x) &  0xf) <<  0)
+
+/* Values for GPMC_CONFIG5 - RdAccessTime and CycleTime timing */
+#define PAGEBURSTACCESSTIME(x)         (((x) &  0xf) << 24)
+#define RDACCESSTIME(x)                        (((x) & 0x1f) << 16)
+#define WRCYCLETIME(x)                 (((x) & 0x1f) <<  8)
+#define RDCYCLETIME(x)                 (((x) & 0x1f) <<  0)
+
+/* Values for GPMC_CONFIG6 - misc timings */
+#define WRACCESSTIME(x)                        (((x) & 0x1f) << 24)
+#define WRDATAONADMUXBUS(x)            (((x) & 0xf) << 16)
+#define CYCLE2CYCLEDELAY(x)            (((x) & 0xf) << 8)
+#define CYCLE2CYCLESAMECSEN            (1 << 7)
+#define CYCLE2CYCLEDIFFCSEN            (1 << 6)
+#define BUSTURNAROUND(x)               (((x) & 0xf) << 0)
+
+/* Values for GPMC_CONFIG7 - CS address mapping configuration */
+#define MASKADDRESS(x)                 (((x) & 0xf) << 8)
+#define CSVALID                                (1 << 6)
+#define BASEADDRESS(x)                 (((x) & 0x3f) << 0)
+
+#define GPMC_CLK               100
+#define NS_TO_CK(ns)           DIV_ROUND_UP((ns) * GPMC_CLK, 1000)
+
+#define _CSWOFF                        NS_TO_CK(tCS_NAND + tCH_NAND)
+#define _CSROFF                        NS_TO_CK(tCEA_NAND + tRP_NAND - tREA_NAND)
+
+#define _ADWOFF                        NS_TO_CK(0)     /* ? */
+#define _ADROFF                        NS_TO_CK(0)     /* ? */
+#define _ADON                  NS_TO_CK(0)     /* ? */
+
+#define _WEOFF                 NS_TO_CK(tCS_NAND)
+#define _WEON                  NS_TO_CK(tCS_NAND - tWP_NAND)
+
+#define _OEOFF                 NS_TO_CK(tCS_NAND + tCH_NAND)
+#define _OEON                  NS_TO_CK(tCEA_NAND - tREA_NAND)
+
+#define _RDACC                 NS_TO_CK(tCEA_NAND)
+#define _WRCYC                 NS_TO_CK(tWC_NAND)
+#define _RDCYC                 NS_TO_CK(tRC_NAND)
+
+#define _WRACC                 NS_TO_CK(tALS_NAND)
+#define _WBURST                        NS_TO_CK(0)
+#define _CSHIGH                        NS_TO_CK(tADL_NAND)
+#define _BTURN                 NS_TO_CK(tRHW_NAND)
+
+#define TX48_NAND_GPMC_CONFIG1 (GPMCFCLKDIVIDER(0) |           \
+                               (0 << 4) /* TIMEPARAGRANULARITY */ | \
+                               MUXADDDATA(0) |                 \
+                               DEVICETYPE_NAND |               \
+                               DEVICESIZE_8BIT |               \
+                               WAITPINSELECT(0) |              \
+                               WAITMONITORINGTIME(0) |         \
+                               (0 << 21) /* WAITWRITEMONITORING */ | \
+                               (0 << 22) /* WAITREADMONITORING */ | \
+                               ATTACHEDDEVICEPAGELENGTH(0) |   \
+                               CLKACTIVATIONTIME(0) |          \
+                               (0 << 27) /* WRITETYPE */ |     \
+                               (0 << 28) /* WRITEMULTIPLE */ | \
+                               (0 << 29) /* READTYPE */ |      \
+                               (0 << 30) /* READMULTIPLE */ |  \
+                               (0 << 31) /* WRAPBURST */)
+/* CONFIG2: Chip Select */
+#define TX48_NAND_GPMC_CONFIG2 (CSWROFFTIME(_CSWOFF) |         \
+                               CSRDOFFTIME(_CSROFF) |          \
+                               CSONTIME(0) |                   \
+                               (0 << 7) /* CSEXTRADELAY */)
+/* CONFIG3: ADV/ALE */
+#define TX48_NAND_GPMC_CONFIG3 (ADVWROFFTIME(_ADWOFF) |        \
+                               ADVRDOFFTIME(_ADROFF) |         \
+                               (0 << 7) /* ADVEXTRADELAY */ |  \
+                               ADVONTIME(_ADON))
+/* CONFIG4: WE/OE */
+#define TX48_NAND_GPMC_CONFIG4 (WEOFFTIME(_WEOFF) |            \
+                               (0 << 23) /* WEEXTRADELAY */ |  \
+                               WEONTIME(_WEON) |               \
+                               OEOFFTIME(_OEOFF) |             \
+                               (0 << 7) /* OEEXTRADELAY */ |   \
+                               OEONTIME(_OEON))
+/* CONFIG5: Cycle Timing */
+#define TX48_NAND_GPMC_CONFIG5 (PAGEBURSTACCESSTIME(0) |       \
+                               RDACCESSTIME(_RDACC) |          \
+                               WRCYCLETIME(_WRCYC) |           \
+                               RDCYCLETIME(_RDCYC))
+/* CONFIG6: Rest of the Pack */
+#define TX48_NAND_GPMC_CONFIG6 (WRACCESSTIME(_WRACC) |         \
+                               WRDATAONADMUXBUS(_WBURST) |     \
+                               CYCLE2CYCLEDELAY(_CSHIGH) |     \
+                               CYCLE2CYCLESAMECSEN |           \
+                               (0 << 6) /* CYCLE2CYCLEDIFFCSEN */ | \
+                               BUSTURNAROUND(_BTURN))
diff --git a/board/karo/tx48/spl.c b/board/karo/tx48/spl.c
new file mode 100644 (file)
index 0000000..2d71d49
--- /dev/null
@@ -0,0 +1,737 @@
+/*
+ * board/karo/tx48/spl.c
+ * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <serial.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <nand.h>
+#include <net.h>
+#include <spl.h>
+#include <linux/mtd/nand.h>
+#include <asm/gpio.h>
+#include <asm/cache.h>
+#include <asm/omap_common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/mem.h>
+#include <video_fb.h>
+#include <asm/arch/da8xx-fb.h>
+
+#include "flash.h"
+
+#define TX48_LED_GPIO          AM33XX_GPIO_NR(1, 26)
+#define TX48_ETH_PHY_RST_GPIO  AM33XX_GPIO_NR(3, 8)
+#define TX48_LCD_RST_GPIO      AM33XX_GPIO_NR(1, 19)
+#define TX48_LCD_PWR_GPIO      AM33XX_GPIO_NR(1, 22)
+#define TX48_LCD_BACKLIGHT_GPIO        AM33XX_GPIO_NR(3, 14)
+
+#define GMII_SEL               (CTRL_BASE + 0x650)
+
+/* UART Defines */
+#define UART_SYSCFG_OFFSET     0x54
+#define UART_SYSSTS_OFFSET     0x58
+
+#define UART_RESET             (0x1 << 1)
+#define UART_RESETDONE         (1 << 0)
+#define UART_IDLE_MODE(m)      (((m) << 3) & UART_IDLE_MODE_MASK)
+#define UART_IDLE_MODE_MASK    (0x3 << 3)
+
+/* Timer Defines */
+#define TSICR_REG              0x54
+#define TIOCP_CFG_REG          0x10
+#define TCLR_REG               0x38
+
+/* RGMII mode define */
+#define RGMII_MODE_ENABLE      0xA
+#define RMII_MODE_ENABLE       0x5
+#define MII_MODE_ENABLE                0x0
+
+#define NO_OF_MAC_ADDR         1
+#define ETH_ALEN               6
+
+/* PAD Control Fields */
+#define SLEWCTRL       (0x1 << 6)
+#define        RXACTIVE        (0x1 << 5)
+#define        PULLUP_EN       (0x1 << 4) /* Pull UP Selection */
+#define PULLUDEN       (0x0 << 3) /* Pull up enabled */
+#define PULLUDDIS      (0x1 << 3) /* Pull up disabled */
+#define MODE(val)      (val)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * PAD CONTROL OFFSETS
+ * Field names corresponds to the pad signal name
+ */
+struct pad_signals {
+       int gpmc_ad0;
+       int gpmc_ad1;
+       int gpmc_ad2;
+       int gpmc_ad3;
+       int gpmc_ad4;
+       int gpmc_ad5;
+       int gpmc_ad6;
+       int gpmc_ad7;
+       int gpmc_ad8;
+       int gpmc_ad9;
+       int gpmc_ad10;
+       int gpmc_ad11;
+       int gpmc_ad12;
+       int gpmc_ad13;
+       int gpmc_ad14;
+       int gpmc_ad15;
+       int gpmc_a0;
+       int gpmc_a1;
+       int gpmc_a2;
+       int gpmc_a3;
+       int gpmc_a4;
+       int gpmc_a5;
+       int gpmc_a6;
+       int gpmc_a7;
+       int gpmc_a8;
+       int gpmc_a9;
+       int gpmc_a10;
+       int gpmc_a11;
+       int gpmc_wait0;
+       int gpmc_wpn;
+       int gpmc_be1n;
+       int gpmc_csn0;
+       int gpmc_csn1;
+       int gpmc_csn2;
+       int gpmc_csn3;
+       int gpmc_clk;
+       int gpmc_advn_ale;
+       int gpmc_oen_ren;
+       int gpmc_wen;
+       int gpmc_be0n_cle;
+       int lcd_data0;
+       int lcd_data1;
+       int lcd_data2;
+       int lcd_data3;
+       int lcd_data4;
+       int lcd_data5;
+       int lcd_data6;
+       int lcd_data7;
+       int lcd_data8;
+       int lcd_data9;
+       int lcd_data10;
+       int lcd_data11;
+       int lcd_data12;
+       int lcd_data13;
+       int lcd_data14;
+       int lcd_data15;
+       int lcd_vsync;
+       int lcd_hsync;
+       int lcd_pclk;
+       int lcd_ac_bias_en;
+       int mmc0_dat3;
+       int mmc0_dat2;
+       int mmc0_dat1;
+       int mmc0_dat0;
+       int mmc0_clk;
+       int mmc0_cmd;
+       int mii1_col;
+       int mii1_crs;
+       int mii1_rxerr;
+       int mii1_txen;
+       int mii1_rxdv;
+       int mii1_txd3;
+       int mii1_txd2;
+       int mii1_txd1;
+       int mii1_txd0;
+       int mii1_txclk;
+       int mii1_rxclk;
+       int mii1_rxd3;
+       int mii1_rxd2;
+       int mii1_rxd1;
+       int mii1_rxd0;
+       int rmii1_refclk;
+       int mdio_data;
+       int mdio_clk;
+       int spi0_sclk;
+       int spi0_d0;
+       int spi0_d1;
+       int spi0_cs0;
+       int spi0_cs1;
+       int ecap0_in_pwm0_out;
+       int uart0_ctsn;
+       int uart0_rtsn;
+       int uart0_rxd;
+       int uart0_txd;
+       int uart1_ctsn;
+       int uart1_rtsn;
+       int uart1_rxd;
+       int uart1_txd;
+       int i2c0_sda;
+       int i2c0_scl;
+       int mcasp0_aclkx;
+       int mcasp0_fsx;
+       int mcasp0_axr0;
+       int mcasp0_ahclkr;
+       int mcasp0_aclkr;
+       int mcasp0_fsr;
+       int mcasp0_axr1;
+       int mcasp0_ahclkx;
+       int xdma_event_intr0;
+       int xdma_event_intr1;
+       int nresetin_out;
+       int porz;
+       int nnmi;
+       int osc0_in;
+       int osc0_out;
+       int rsvd1;
+       int tms;
+       int tdi;
+       int tdo;
+       int tck;
+       int ntrst;
+       int emu0;
+       int emu1;
+       int osc1_in;
+       int osc1_out;
+       int pmic_power_en;
+       int rtc_porz;
+       int rsvd2;
+       int ext_wakeup;
+       int enz_kaldo_1p8v;
+       int usb0_dm;
+       int usb0_dp;
+       int usb0_ce;
+       int usb0_id;
+       int usb0_vbus;
+       int usb0_drvvbus;
+       int usb1_dm;
+       int usb1_dp;
+       int usb1_ce;
+       int usb1_id;
+       int usb1_vbus;
+       int usb1_drvvbus;
+       int ddr_resetn;
+       int ddr_csn0;
+       int ddr_cke;
+       int ddr_ck;
+       int ddr_nck;
+       int ddr_casn;
+       int ddr_rasn;
+       int ddr_wen;
+       int ddr_ba0;
+       int ddr_ba1;
+       int ddr_ba2;
+       int ddr_a0;
+       int ddr_a1;
+       int ddr_a2;
+       int ddr_a3;
+       int ddr_a4;
+       int ddr_a5;
+       int ddr_a6;
+       int ddr_a7;
+       int ddr_a8;
+       int ddr_a9;
+       int ddr_a10;
+       int ddr_a11;
+       int ddr_a12;
+       int ddr_a13;
+       int ddr_a14;
+       int ddr_a15;
+       int ddr_odt;
+       int ddr_d0;
+       int ddr_d1;
+       int ddr_d2;
+       int ddr_d3;
+       int ddr_d4;
+       int ddr_d5;
+       int ddr_d6;
+       int ddr_d7;
+       int ddr_d8;
+       int ddr_d9;
+       int ddr_d10;
+       int ddr_d11;
+       int ddr_d12;
+       int ddr_d13;
+       int ddr_d14;
+       int ddr_d15;
+       int ddr_dqm0;
+       int ddr_dqm1;
+       int ddr_dqs0;
+       int ddr_dqsn0;
+       int ddr_dqs1;
+       int ddr_dqsn1;
+       int ddr_vref;
+       int ddr_vtp;
+       int ddr_strben0;
+       int ddr_strben1;
+       int ain7;
+       int ain6;
+       int ain5;
+       int ain4;
+       int ain3;
+       int ain2;
+       int ain1;
+       int ain0;
+       int vrefp;
+       int vrefn;
+};
+
+struct pin_mux {
+       short reg_offset;
+       uint8_t val;
+};
+
+#define PAD_CTRL_BASE  0x800
+#define OFFSET(x)      (unsigned int) (&((struct pad_signals *) \
+                               (PAD_CTRL_BASE))->x)
+
+static struct pin_mux tx48_pins[] = {
+#ifdef CONFIG_CMD_NAND
+       { OFFSET(gpmc_ad0), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD0 */
+       { OFFSET(gpmc_ad1), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD1 */
+       { OFFSET(gpmc_ad2), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD2 */
+       { OFFSET(gpmc_ad3), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD3 */
+       { OFFSET(gpmc_ad4), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD4 */
+       { OFFSET(gpmc_ad5), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD5 */
+       { OFFSET(gpmc_ad6), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD6 */
+       { OFFSET(gpmc_ad7), MODE(0) | PULLUP_EN | RXACTIVE, },  /* NAND AD7 */
+       { OFFSET(gpmc_wait0), MODE(0) | RXACTIVE | PULLUP_EN, }, /* NAND WAIT */
+       { OFFSET(gpmc_wpn), MODE(7) | PULLUP_EN | RXACTIVE, },  /* NAND_WPN */
+       { OFFSET(gpmc_csn0), MODE(0) | PULLUDEN, },     /* NAND_CS0 */
+       { OFFSET(gpmc_advn_ale), MODE(0) | PULLUDEN, }, /* NAND_ADV_ALE */
+       { OFFSET(gpmc_oen_ren), MODE(0) | PULLUDEN, },  /* NAND_OE */
+       { OFFSET(gpmc_wen), MODE(0) | PULLUDEN, },      /* NAND_WEN */
+       { OFFSET(gpmc_be0n_cle), MODE(0) | PULLUDEN, }, /* NAND_BE_CLE */
+#endif
+       /* I2C0 */
+       { OFFSET(i2c0_sda), MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL, }, /* I2C_DATA */
+       { OFFSET(i2c0_scl), MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL, }, /* I2C_SCLK */
+
+#ifndef CONFIG_NO_ETH
+       /* RMII1 */
+       { OFFSET(mii1_crs), MODE(1) | RXACTIVE, },      /* RMII1_CRS */
+       { OFFSET(mii1_rxerr), MODE(1) | RXACTIVE | PULLUDEN, },  /* RMII1_RXERR */
+       { OFFSET(mii1_txen), MODE(1), },                     /* RMII1_TXEN */
+       { OFFSET(mii1_txd1), MODE(1), },                     /* RMII1_TXD1 */
+       { OFFSET(mii1_txd0), MODE(1), },                     /* RMII1_TXD0 */
+       { OFFSET(mii1_rxd1), MODE(1) | RXACTIVE | PULLUP_EN, }, /* RMII1_RXD1 */
+       { OFFSET(mii1_rxd0), MODE(1) | RXACTIVE | PULLUP_EN, }, /* RMII1_RXD0 */
+       { OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN, }, /* MDIO_DATA */
+       { OFFSET(mdio_clk), MODE(0) | PULLUP_EN, },     /* MDIO_CLK */
+       { OFFSET(rmii1_refclk), MODE(0) | RXACTIVE, },  /* RMII1_REFCLK */
+       { OFFSET(emu0), MODE(7) | RXACTIVE},         /* nINT */
+       { OFFSET(emu1), MODE(7), },                  /* nRST */
+#endif
+};
+
+static struct gpio tx48_gpios[] = {
+       /* configure this pin early to prevent flicker of the LCD */
+       { TX48_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+};
+
+static struct pin_mux tx48_mmc_pins[] = {
+#ifdef CONFIG_OMAP_HSMMC
+       /* MMC1 */
+       { OFFSET(mii1_rxd2), MODE(4) | RXACTIVE | PULLUP_EN, }, /* MMC1_DAT3 */
+       { OFFSET(mii1_rxd3), MODE(4) | RXACTIVE | PULLUP_EN, }, /* MMC1_DAT2 */
+       { OFFSET(mii1_rxclk), MODE(4) | RXACTIVE | PULLUP_EN, }, /* MMC1_DAT1 */
+       { OFFSET(mii1_txclk), MODE(4) | RXACTIVE | PULLUP_EN, }, /* MMC1_DAT0 */
+       { OFFSET(gpmc_csn1), MODE(2) | RXACTIVE | PULLUP_EN, }, /* MMC1_CLK */
+       { OFFSET(gpmc_csn2), MODE(2) | RXACTIVE | PULLUP_EN, }, /* MMC1_CMD */
+       { OFFSET(mcasp0_fsx), MODE(4) | RXACTIVE, },    /* MMC1_CD */
+#endif
+};
+
+/*
+ * Configure the pin mux for the module
+ */
+static inline void tx48_set_pin_mux(const struct pin_mux *pin_mux,
+                       int num_pins)
+{
+       int i;
+
+       for (i = 0; i < num_pins; i++)
+               writel(pin_mux[i].val, CTRL_BASE + pin_mux[i].reg_offset);
+}
+
+static struct pin_mux tx48_uart0_pins[] = {
+#ifdef CONFIG_SYS_NS16550_COM1
+       /* UART0 for early boot messages */
+       { OFFSET(uart0_rxd), MODE(0) | PULLUP_EN | RXACTIVE, }, /* UART0_RXD */
+       { OFFSET(uart0_txd), MODE(0) | PULLUDEN, },             /* UART0_TXD */
+       { OFFSET(uart0_ctsn), MODE(0) | PULLUP_EN | RXACTIVE, },/* UART0_CTS */
+       { OFFSET(uart0_rtsn), MODE(0) | PULLUDEN, },            /* UART0_RTS */
+#endif
+#ifdef CONFIG_SYS_NS16550_COM2
+       /* UART1 */
+       { OFFSET(uart1_rxd), MODE(0) | PULLUP_EN | RXACTIVE, }, /* UART1_RXD */
+       { OFFSET(uart1_txd), MODE(0) | PULLUDEN, },             /* UART1_TXD */
+       { OFFSET(uart1_ctsn), MODE(0) | PULLUP_EN | RXACTIVE, },/* UART1_CTS */
+       { OFFSET(uart1_rtsn), MODE(0) | PULLUDEN, },            /* UART1_RTS */
+#endif
+#ifdef CONFIG_SYS_NS16550_COM3
+       /* UART5 */
+       { OFFSET(mii1_rxdv), MODE(3) | PULLUP_EN | RXACTIVE, }, /* UART5_RXD */
+       { OFFSET(mii1_col), MODE(3) | PULLUDEN, },              /* UART5_TXD */
+       { OFFSET(mmc0_dat1), MODE(2) | PULLUP_EN | RXACTIVE, }, /* UART5_CTS */
+       { OFFSET(mmc0_dat0), MODE(2) | PULLUDEN, },             /* UART5_RTS */
+#endif
+};
+
+/*
+ * early system init of muxing and clocks.
+ */
+static void enable_uart0_pin_mux(void)
+{
+       tx48_set_pin_mux(tx48_uart0_pins, ARRAY_SIZE(tx48_uart0_pins));
+}
+
+static void enable_mmc0_pin_mux(void)
+{
+       tx48_set_pin_mux(tx48_mmc_pins, ARRAY_SIZE(tx48_mmc_pins));
+}
+
+static const u32 gpmc_nand_cfg[GPMC_MAX_REG] = {
+       TX48_NAND_GPMC_CONFIG1,
+       TX48_NAND_GPMC_CONFIG2,
+       TX48_NAND_GPMC_CONFIG3,
+       TX48_NAND_GPMC_CONFIG4,
+       TX48_NAND_GPMC_CONFIG5,
+       TX48_NAND_GPMC_CONFIG6,
+};
+
+#define SDRAM_CLK              CONFIG_SYS_DDR_CLK
+
+#define ns_TO_ck(ns)           (((ns) * SDRAM_CLK + 999) / 1000)
+#define ck_TO_ns(ck)           ((ck) * 1000 / SDRAM_CLK)
+
+#ifdef DEBUG
+static inline unsigned ck_val_check(unsigned ck, unsigned offs, unsigned max,
+                       const char *name)
+{
+       if (ck < offs) {
+               printf("value %u for parameter %s is out of range (min: %u\n",
+                       ck, name, offs);
+               hang();
+       }
+       if (ck > max) {
+               printf("value %u for parameter %s is out of range (max: %u\n",
+                       ck, name, max);
+               hang();
+       }
+       return ck - offs;
+}
+#define CK_VAL(ck, offs, max)  ck_val_check(ck, offs, max, #ck)
+#else
+#define CK_VAL(ck, offs, max)  ((ck) - (offs))
+#endif
+
+#define DDR3_NT5CB128          1
+#define DDR3_H5TQ2G8           2
+
+#if 1
+#define SDRAM_TYPE DDR3_NT5CB128
+#else
+#define SDRAM_TYPE DDR3_H5TQ2G8
+#endif
+
+#ifndef SDRAM_TYPE
+#error No SDRAM_TYPE specified
+#elif (SDRAM_TYPE == DDR3_NT5CB128) || (SDRAM_TYPE == DDR3_H5TQ2G8)
+#define tRP                    ns_TO_ck(14)
+#define tRCD                   ns_TO_ck(14)
+#define tWR                    ns_TO_ck(15)
+#define tRAS                   ns_TO_ck(35)
+#define tRC                    ns_TO_ck(49)
+#define tRRD                   max(ns_TO_ck(8), 4)
+#define tWTR                   max(ns_TO_ck(8), 4)
+
+#define tXP                    max(ns_TO_ck(6), 3)
+#define tXPR                   max(5, ns_TO_ck(ck_TO_ns(tRFC + 1) + 10))
+#define tODT                   ns_TO_ck(9)
+#define tXSNR                  max(5, ns_TO_ck(ck_TO_ns(tRFC + 1) + 10))
+#define tXSRD                  512
+#define tRTP                   max(ns_TO_ck(8), 4)
+#define tCKE                   max(ns_TO_ck(6), 3)
+
+#define tPDLL_UL               512
+#define tZQCS                  64
+#define tRFC                   ns_TO_ck(160)
+#define tRAS_MAX               0xf
+
+static inline int cwl(u32 sdram_clk)
+{
+       if (sdram_clk <= 300)
+               return 5;
+       else if (sdram_clk > 300 && sdram_clk <= 333)
+               return 5;
+       else if (sdram_clk > 333 && sdram_clk <= 400)
+               return 5;
+       else if (sdram_clk > 400 && sdram_clk <= 533)
+               return 6;
+       else if (sdram_clk > 533 && sdram_clk <= 666)
+               return 7;
+       else if (SDRAM_TYPE != DDR3_H5TQ2G8)
+               ;
+       else if (sdram_clk > 666 && sdram_clk <= 800)
+               return 8;
+
+       printf("SDRAM clock out of range\n");
+       hang();
+}
+#define CWL cwl(SDRAM_CLK)
+
+static inline int cl(u32 sdram_clk)
+{
+       if (sdram_clk <= 300)
+               return 5;
+       else if (sdram_clk > 300 && sdram_clk <= 333)
+               return 5;
+       else if (sdram_clk > 333 && sdram_clk <= 400)
+               return 6;
+       else if (sdram_clk > 400 && sdram_clk <= 533)
+               return 8;
+       else if (sdram_clk > 533 && sdram_clk <= 666)
+               return (SDRAM_TYPE == DDR3_H5TQ2G8) ? 10 : 9;
+       else if (SDRAM_TYPE != DDR3_H5TQ2G8)
+               ;
+       else if (sdram_clk > 666 && sdram_clk <= 800)
+               return 11;
+
+       printf("SDRAM clock out of range\n");
+       hang();
+}
+#define CL cl(SDRAM_CLK)
+
+#define ROW_ADDR_BITS          14
+#define SDRAM_PG_SIZE          1024
+#else
+#error Unsupported SDRAM_TYPE specified
+#endif
+
+#define SDRAM_CONFIG_VAL       (                                       \
+               (3 << 29) /* SDRAM type: 0: DDR1 1: LPDDR1 2: DDR2 3: DDR3 */ | \
+               (0 << 27) /* IBANK pos */ |                             \
+               (2 << 24) /* termination resistor value 0: disable 1: RZQ/4 2: RZQ/2 3: RZQ/6 4: RZQ/12 5: RZQ/8 */ | \
+               (0 << 23) /* DDR2 differential DQS */ |                 \
+               (1 << 21) /* dynamic ODT 0: off 1: RZQ/4 2: RZQ/2 */ |  \
+               (0 << 20) /* DLL disable */ |                           \
+               (1 << 18) /* drive strength 0: RZQ/6 1: RZQ/7 */ |      \
+               ((CWL - 5) << 16) /* CWL 0: 5 ... 3: 8 */ |             \
+               (1 << 14) /* SDRAM data bus width 0: 32 1: 16 */ |      \
+               (((CL - 4) * 2) << 10) /* CAS latency 2: 5 4: 6 6: 8 ... 14: 11 (DDR3) */ | \
+               ((ROW_ADDR_BITS - 9) << 7) /* # of row addr bits 0: 9 ... 7: 16 */ | \
+               (3 << 4) /* # of SDRAM internal banks 0: 1 1: 2 2: 4 3: 8 */ | \
+               (0 << 3) /* # of CS lines */ |                          \
+               ((ffs(SDRAM_PG_SIZE / 256) - 1) << 0) /* page size 0: 256 1: 512 2: 1024 3:2048 */ | \
+               0)
+
+#define SDREF_VAL              (                                       \
+               (0 << 31) /* */ |                                       \
+               (1 << 29) /* self refresh temperature range 1: extended temp range */ | \
+               (0 << 28) /* auto self refresh enable */ |              \
+               (0 << 24) /* partial array self refresh */ |            \
+               ((SDRAM_CLK * 7800 / 1000) << 0) /* refresh interval */ | \
+               0)
+
+#define tFAW           ns_TO_ck(45)
+
+#define SDRAM_TIM1_VAL ((CK_VAL(tRP, 1, 16) << 25) |   \
+                        (CK_VAL(tRCD, 1, 16) << 21) |  \
+                        (CK_VAL(tWR, 1, 16) << 17) |   \
+                        (CK_VAL(tRAS, 1, 32) << 12) |  \
+                        (CK_VAL(tRC, 1, 64) << 6) |    \
+                        (CK_VAL(tRRD, 1, 8) << 3) |    \
+                        (CK_VAL(tWTR, 1, 8) << 0))
+
+#define SDRAM_TIM2_VAL ((CK_VAL(max(tCKE, tXP), 1, 8) << 28) | \
+                        (CK_VAL(tODT, 0, 8) << 25) |           \
+                        (CK_VAL(tXSNR, 1, 128) << 16) |        \
+                        (CK_VAL(tXSRD, 1, 1024) << 6) |        \
+                        (CK_VAL(tRTP, 1, 8) << 3) |            \
+                        (CK_VAL(tCKE, 1, 8) << 0))
+
+#define SDRAM_TIM3_VAL ((CK_VAL(DIV_ROUND_UP(tPDLL_UL, 128), 0, 16) << 28) | \
+                        (CK_VAL(tZQCS, 1, 64) << 15) |                 \
+                        (CK_VAL(tRFC, 1, 1024) << 4) |                 \
+                        (CK_VAL(tRAS_MAX, 0, 16) << 0))
+
+#define ZQ_CONFIG_VAL          (                                       \
+               (1 << 31) /* ZQ calib for CS1 */ |                      \
+               (0 << 30) /* ZQ calib for CS0 */ |                      \
+               (0 << 29) /* dual calib */ |                            \
+               (1 << 28) /* ZQ calib on SR/PWDN exit */ |              \
+               (2 << 18) /* ZQCL intervals for ZQINIT */ |             \
+               (4 << 16) /* ZQCS intervals for ZQCL */ |               \
+               (80 << 0) /* refr periods between ZQCS commands */ |    \
+               0)
+
+static struct ddr_data tx48_ddr3_data = {
+       /* reset defaults */
+       .datardsratio0 = 0x04010040,
+       .datawdsratio0 = 0x0,
+       .datafwsratio0 = 0x0,
+       .datawrsratio0 = 0x04010040,
+       .datadldiff0 = 0x4,
+};
+
+static struct cmd_control tx48_ddr3_cmd_ctrl_data = {
+       /* reset defaults */
+       .cmd0csratio = 0x80,
+       .cmd0dldiff = 0x04,
+       .cmd1csratio = 0x80,
+       .cmd1dldiff = 0x04,
+       .cmd2csratio = 0x80,
+       .cmd2dldiff = 0x04,
+};
+
+static void ddr3_calib_start(void)
+{
+       static struct emif_reg_struct *emif_reg = (void *)EMIF4_0_CFG_BASE;
+       int loops = 0;
+       u32 regval;
+       u32 emif_status;
+
+       debug("Starting DDR3 calibration\n");
+
+       /* wait for DDR PHY ready */
+       while (!((emif_status = readl(&emif_reg->emif_status)) & (1 << 2))) {
+               if (loops++ > 100000)
+                       break;
+               udelay(1);
+       }
+       debug("EMIF status: %08x after %u loops\n", emif_status, loops);
+
+       /* enable DDR3 write levelling */
+       loops = 0;
+       writel(EMIF_REG_RDWRLVLFULL_START_MASK, &emif_reg->emif_rd_wr_lvl_ctl);
+       do {
+               regval = readl(&emif_reg->emif_rd_wr_lvl_ctl);
+               if (!(regval & EMIF_REG_RDWRLVLFULL_START_MASK))
+                       break;
+               udelay(1);
+       } while (loops++ < 100000);
+       if (regval & EMIF_REG_RDWRLVLFULL_START_MASK) {
+               printf("Full WRLVL timed out\n");
+       } else {
+               debug("Full Write Levelling done after %u us\n", loops);
+       }
+       writel(0, &emif_reg->emif_rd_wr_lvl_rmp_ctl);
+       writel(0, &emif_reg->emif_rd_wr_lvl_rmp_win);
+       writel(0x0f808080, &emif_reg->emif_rd_wr_lvl_ctl);
+       debug("DDR3 calibration done\n");
+}
+
+static void tx48_ddr_init(void)
+{
+       struct emif_regs r = {0};
+
+       debug("Initialising SDRAM timing for %u MHz DDR clock\n", SDRAM_CLK);
+
+       r.sdram_config = SDRAM_CONFIG_VAL;
+       r.ref_ctrl = SDREF_VAL;
+       r.sdram_tim1 = SDRAM_TIM1_VAL;
+       r.sdram_tim2 = SDRAM_TIM2_VAL;
+       r.sdram_tim3 = SDRAM_TIM3_VAL;
+       r.zq_config = ZQ_CONFIG_VAL;
+       r.emif_ddr_phy_ctlr_1 = 0x0000030b;
+
+       config_ddr(SDRAM_CLK, 0x04, &tx48_ddr3_data,
+               &tx48_ddr3_cmd_ctrl_data, &r, 0);
+
+       ddr3_calib_start();
+
+       debug("%s: config_ddr done\n", __func__);
+}
+
+#ifdef CONFIG_HW_WATCHDOG
+static inline void tx48_wdog_disable(void)
+{
+}
+#else
+static inline void tx48_wdog_disable(void)
+{
+       struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+
+       /* WDT1 is already running when the bootloader gets control
+        * Disable it to avoid "random" resets
+        */
+       writel(0xAAAA, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) != 0x0)
+               ;
+       writel(0x5555, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) != 0x0)
+               ;
+}
+#endif
+
+void s_init(void)
+{
+       struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
+       struct gpmc *gpmc_cfg = (struct gpmc *)GPMC_BASE;
+       int timeout = 1000;
+
+       gd = &gdata;
+
+       /*
+         * Save the boot parameters passed from romcode.
+         * We cannot delay the saving further than this,
+         * to prevent overwrites.
+         */
+       save_omap_boot_params();
+
+       /* Setup the PLLs and the clocks for the peripherals */
+       pll_init();
+
+       tx48_wdog_disable();
+
+       enable_uart0_pin_mux();
+
+       /* UART softreset */
+       writel(readl(&uart_base->uartsyscfg) | UART_RESET,
+               &uart_base->uartsyscfg);
+       while (!(readl(&uart_base->uartsyssts) & UART_RESETDONE)) {
+               udelay(1);
+               if (timeout-- <= 0)
+                       break;
+       }
+
+       /* Disable smart idle */
+       writel((readl(&uart_base->uartsyscfg) & ~UART_IDLE_MODE_MASK) |
+               UART_IDLE_MODE(1), &uart_base->uartsyscfg);
+
+       preloader_console_init();
+
+       if (timeout <= 0)
+               printf("Timeout waiting for UART RESET\n");
+
+       timer_init();
+
+       tx48_ddr_init();
+
+       gpmc_init();
+       enable_gpmc_cs_config(gpmc_nand_cfg, &gpmc_cfg->cs[0],
+                       CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_SIZE);
+
+       /* Enable MMC0 */
+       enable_mmc0_pin_mux();
+
+       gpio_request_array(tx48_gpios, ARRAY_SIZE(tx48_gpios));
+       tx48_set_pin_mux(tx48_pins, ARRAY_SIZE(tx48_pins));
+}
diff --git a/board/karo/tx48/tx48.c b/board/karo/tx48/tx48.c
new file mode 100644 (file)
index 0000000..da17a32
--- /dev/null
@@ -0,0 +1,1171 @@
+/*
+ * Copyright (C) 2012-2013 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * based on evm.c
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <serial.h>
+#include <libfdt.h>
+#include <lcd.h>
+#include <fdt_support.h>
+#include <nand.h>
+#include <net.h>
+#include <linux/mtd/nand.h>
+#include <linux/fb.h>
+#include <asm/gpio.h>
+#include <asm/cache.h>
+#include <asm/omap_common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clock.h>
+#include <video_fb.h>
+#include <asm/arch/da8xx-fb.h>
+
+#include "../common/karo.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TX48_LED_GPIO          AM33XX_GPIO_NR(1, 26)
+#define TX48_ETH_PHY_RST_GPIO  AM33XX_GPIO_NR(3, 8)
+#define TX48_LCD_RST_GPIO      AM33XX_GPIO_NR(1, 19)
+#define TX48_LCD_PWR_GPIO      AM33XX_GPIO_NR(1, 22)
+#define TX48_LCD_BACKLIGHT_GPIO        AM33XX_GPIO_NR(3, 14)
+#define TX48_MMC_CD_GPIO       AM33XX_GPIO_NR(3, 15)
+
+#define GMII_SEL               (CTRL_BASE + 0x650)
+
+/* UART Defines */
+#define UART_SYSCFG_OFFSET     0x54
+#define UART_SYSSTS_OFFSET     0x58
+
+#define UART_RESET             (0x1 << 1)
+#define UART_CLK_RUNNING_MASK  0x1
+#define UART_SMART_IDLE_EN     (0x1 << 0x3)
+
+/* Timer Defines */
+#define TSICR_REG              0x54
+#define TIOCP_CFG_REG          0x10
+#define TCLR_REG               0x38
+
+/* RGMII mode define */
+#define RGMII_MODE_ENABLE      0xA
+#define RMII_MODE_ENABLE       0x5
+#define MII_MODE_ENABLE                0x0
+
+#define NO_OF_MAC_ADDR         1
+#define ETH_ALEN               6
+
+/* PAD Control Fields */
+#define SLEWCTRL       (0x1 << 6)
+#define        RXACTIVE        (0x1 << 5)
+#define        PULLUP_EN       (0x1 << 4) /* Pull UP Selection */
+#define PULLUDEN       (0x0 << 3) /* Pull up enabled */
+#define PULLUDDIS      (0x1 << 3) /* Pull up disabled */
+#define MODE(val)      (val)
+
+/*
+ * PAD CONTROL OFFSETS
+ * Field names corresponds to the pad signal name
+ */
+struct pad_signals {
+       int gpmc_ad0;
+       int gpmc_ad1;
+       int gpmc_ad2;
+       int gpmc_ad3;
+       int gpmc_ad4;
+       int gpmc_ad5;
+       int gpmc_ad6;
+       int gpmc_ad7;
+       int gpmc_ad8;
+       int gpmc_ad9;
+       int gpmc_ad10;
+       int gpmc_ad11;
+       int gpmc_ad12;
+       int gpmc_ad13;
+       int gpmc_ad14;
+       int gpmc_ad15;
+       int gpmc_a0;
+       int gpmc_a1;
+       int gpmc_a2;
+       int gpmc_a3;
+       int gpmc_a4;
+       int gpmc_a5;
+       int gpmc_a6;
+       int gpmc_a7;
+       int gpmc_a8;
+       int gpmc_a9;
+       int gpmc_a10;
+       int gpmc_a11;
+       int gpmc_wait0;
+       int gpmc_wpn;
+       int gpmc_be1n;
+       int gpmc_csn0;
+       int gpmc_csn1;
+       int gpmc_csn2;
+       int gpmc_csn3;
+       int gpmc_clk;
+       int gpmc_advn_ale;
+       int gpmc_oen_ren;
+       int gpmc_wen;
+       int gpmc_be0n_cle;
+       int lcd_data0;
+       int lcd_data1;
+       int lcd_data2;
+       int lcd_data3;
+       int lcd_data4;
+       int lcd_data5;
+       int lcd_data6;
+       int lcd_data7;
+       int lcd_data8;
+       int lcd_data9;
+       int lcd_data10;
+       int lcd_data11;
+       int lcd_data12;
+       int lcd_data13;
+       int lcd_data14;
+       int lcd_data15;
+       int lcd_vsync;
+       int lcd_hsync;
+       int lcd_pclk;
+       int lcd_ac_bias_en;
+       int mmc0_dat3;
+       int mmc0_dat2;
+       int mmc0_dat1;
+       int mmc0_dat0;
+       int mmc0_clk;
+       int mmc0_cmd;
+       int mii1_col;
+       int mii1_crs;
+       int mii1_rxerr;
+       int mii1_txen;
+       int mii1_rxdv;
+       int mii1_txd3;
+       int mii1_txd2;
+       int mii1_txd1;
+       int mii1_txd0;
+       int mii1_txclk;
+       int mii1_rxclk;
+       int mii1_rxd3;
+       int mii1_rxd2;
+       int mii1_rxd1;
+       int mii1_rxd0;
+       int rmii1_refclk;
+       int mdio_data;
+       int mdio_clk;
+       int spi0_sclk;
+       int spi0_d0;
+       int spi0_d1;
+       int spi0_cs0;
+       int spi0_cs1;
+       int ecap0_in_pwm0_out;
+       int uart0_ctsn;
+       int uart0_rtsn;
+       int uart0_rxd;
+       int uart0_txd;
+       int uart1_ctsn;
+       int uart1_rtsn;
+       int uart1_rxd;
+       int uart1_txd;
+       int i2c0_sda;
+       int i2c0_scl;
+       int mcasp0_aclkx;
+       int mcasp0_fsx;
+       int mcasp0_axr0;
+       int mcasp0_ahclkr;
+       int mcasp0_aclkr;
+       int mcasp0_fsr;
+       int mcasp0_axr1;
+       int mcasp0_ahclkx;
+       int xdma_event_intr0;
+       int xdma_event_intr1;
+       int nresetin_out;
+       int porz;
+       int nnmi;
+       int osc0_in;
+       int osc0_out;
+       int rsvd1;
+       int tms;
+       int tdi;
+       int tdo;
+       int tck;
+       int ntrst;
+       int emu0;
+       int emu1;
+       int osc1_in;
+       int osc1_out;
+       int pmic_power_en;
+       int rtc_porz;
+       int rsvd2;
+       int ext_wakeup;
+       int enz_kaldo_1p8v;
+       int usb0_dm;
+       int usb0_dp;
+       int usb0_ce;
+       int usb0_id;
+       int usb0_vbus;
+       int usb0_drvvbus;
+       int usb1_dm;
+       int usb1_dp;
+       int usb1_ce;
+       int usb1_id;
+       int usb1_vbus;
+       int usb1_drvvbus;
+       int ddr_resetn;
+       int ddr_csn0;
+       int ddr_cke;
+       int ddr_ck;
+       int ddr_nck;
+       int ddr_casn;
+       int ddr_rasn;
+       int ddr_wen;
+       int ddr_ba0;
+       int ddr_ba1;
+       int ddr_ba2;
+       int ddr_a0;
+       int ddr_a1;
+       int ddr_a2;
+       int ddr_a3;
+       int ddr_a4;
+       int ddr_a5;
+       int ddr_a6;
+       int ddr_a7;
+       int ddr_a8;
+       int ddr_a9;
+       int ddr_a10;
+       int ddr_a11;
+       int ddr_a12;
+       int ddr_a13;
+       int ddr_a14;
+       int ddr_a15;
+       int ddr_odt;
+       int ddr_d0;
+       int ddr_d1;
+       int ddr_d2;
+       int ddr_d3;
+       int ddr_d4;
+       int ddr_d5;
+       int ddr_d6;
+       int ddr_d7;
+       int ddr_d8;
+       int ddr_d9;
+       int ddr_d10;
+       int ddr_d11;
+       int ddr_d12;
+       int ddr_d13;
+       int ddr_d14;
+       int ddr_d15;
+       int ddr_dqm0;
+       int ddr_dqm1;
+       int ddr_dqs0;
+       int ddr_dqsn0;
+       int ddr_dqs1;
+       int ddr_dqsn1;
+       int ddr_vref;
+       int ddr_vtp;
+       int ddr_strben0;
+       int ddr_strben1;
+       int ain7;
+       int ain6;
+       int ain5;
+       int ain4;
+       int ain3;
+       int ain2;
+       int ain1;
+       int ain0;
+       int vrefp;
+       int vrefn;
+};
+
+struct pin_mux {
+       short reg_offset;
+       uint8_t val;
+};
+
+#define PAD_CTRL_BASE  0x800
+#define OFFSET(x)      (unsigned int) (&((struct pad_signals *) \
+                               (PAD_CTRL_BASE))->x)
+
+/*
+ * Configure the pin mux for the module
+ */
+static inline void tx48_set_pin_mux(const struct pin_mux *pin_mux,
+                       int num_pins)
+{
+       int i;
+
+       for (i = 0; i < num_pins; i++)
+               writel(pin_mux[i].val, CTRL_BASE + pin_mux[i].reg_offset);
+}
+
+#define PRM_RSTST_GLOBAL_COLD_RST      (1 << 0)
+#define PRM_RSTST_GLOBAL_WARM_SW_RST   (1 << 1)
+#define PRM_RSTST_WDT1_RST             (1 << 4)
+#define PRM_RSTST_EXTERNAL_WARM_RST    (1 << 5)
+#define PRM_RSTST_ICEPICK_RST          (1 << 9)
+
+static u32 prm_rstst __attribute__((section(".data")));
+
+/*
+ * Basic board specific setup
+ */
+static const struct pin_mux tx48_pads[] = {
+       { OFFSET(i2c0_sda), MODE(7) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(i2c0_scl), MODE(7) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(emu1), MODE(7), }, /* ETH PHY Reset */
+};
+
+static const struct pin_mux tx48_i2c_pads[] = {
+       { OFFSET(i2c0_sda), MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+       { OFFSET(i2c0_scl), MODE(0) | RXACTIVE | PULLUDEN | PULLUP_EN, },
+};
+
+static const struct gpio tx48_gpios[] = {
+       { AM33XX_GPIO_NR(3, 5), GPIOFLAG_INPUT, "I2C1_SDA", },
+       { AM33XX_GPIO_NR(3, 6), GPIOFLAG_INPUT, "I2C1_SCL", },
+       { AM33XX_GPIO_NR(3, 8), GPIOFLAG_OUTPUT_INIT_LOW, "ETH_PHY_RESET", },
+};
+
+static const struct pin_mux stk5_pads[] = {
+       /* heartbeat LED */
+       { OFFSET(gpmc_a10), MODE(7) | PULLUDEN, },
+       /* LCD RESET */
+       { OFFSET(gpmc_a3), MODE(7) | PULLUDEN, },
+       /* LCD POWER_ENABLE */
+       { OFFSET(gpmc_a6), MODE(7) | PULLUDEN, },
+       /* LCD Backlight (PWM) */
+       { OFFSET(mcasp0_aclkx), MODE(7) | PULLUDEN, },
+       /* MMC CD */
+       { OFFSET(mcasp0_fsx), MODE(7) | PULLUDEN | PULLUP_EN, },
+};
+
+static const struct gpio stk5_gpios[] = {
+       { TX48_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
+       { TX48_MMC_CD_GPIO, GPIOFLAG_INPUT, "MMC0 CD", },
+};
+
+static const struct pin_mux stk5_lcd_pads[] = {
+       /* LCD data bus */
+       { OFFSET(lcd_data0), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data1), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data2), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data3), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data4), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data5), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data6), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data7), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data8), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data9), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data10), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data11), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data12), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data13), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data14), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_data15), MODE(0) | PULLUDEN, },
+       /* LCD control signals */
+       { OFFSET(lcd_hsync), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_vsync), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_pclk), MODE(0) | PULLUDEN, },
+       { OFFSET(lcd_ac_bias_en), MODE(0) | PULLUDEN, },
+};
+
+static const struct gpio stk5_lcd_gpios[] = {
+       { AM33XX_GPIO_NR(1, 19), GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
+       { AM33XX_GPIO_NR(1, 22), GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
+       { AM33XX_GPIO_NR(3, 14), GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+};
+
+static const struct pin_mux stk5v5_pads[] = {
+       /* CAN transceiver control */
+       { OFFSET(gpmc_ad8), MODE(7) | PULLUDEN, },
+};
+
+static const struct gpio stk5v5_gpios[] = {
+       { AM33XX_GPIO_NR(0, 22), GPIOFLAG_OUTPUT_INIT_HIGH, "CAN XCVR", },
+};
+
+#ifdef CONFIG_LCD
+static u16 tx48_cmap[256];
+vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1366,
+       .vl_row = 768,
+
+       .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx48_cmap,
+};
+
+#define FB_SYNC_OE_LOW_ACT     (1 << 31)
+#define FB_SYNC_CLK_LAT_FALL   (1 << 30)
+
+static struct fb_videomode tx48_fb_modes[] = {
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+};
+
+void *lcd_base;                        /* Start of framebuffer memory  */
+void *lcd_console_address;     /* Start of console buffer      */
+
+int lcd_color_fg;
+int lcd_color_bg;
+
+short console_col;
+short console_row;
+
+static int lcd_enabled = 1;
+static int lcd_bl_polarity;
+
+static int lcd_backlight_polarity(void)
+{
+       return lcd_bl_polarity;
+}
+
+void lcd_initcolregs(void)
+{
+}
+
+void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
+{
+}
+
+void lcd_enable(void)
+{
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+
+       if (lcd_enabled) {
+               karo_load_splashimage(1);
+
+               debug("Switching LCD on\n");
+               gpio_set_value(TX48_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX48_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX48_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+}
+
+void lcd_disable(void)
+{
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               da8xx_fb_disable();
+               lcd_enabled = 0;
+       }
+}
+
+static void tx48_lcd_panel_setup(struct da8xx_panel *p,
+                               struct fb_videomode *fb)
+{
+       p->pxl_clk = PICOS2KHZ(fb->pixclock) * 1000;
+
+       p->width = fb->xres;
+       p->hbp = fb->left_margin;
+       p->hsw = fb->hsync_len;
+       p->hfp = fb->right_margin;
+
+       p->height = fb->yres;
+       p->vbp = fb->upper_margin;
+       p->vsw = fb->vsync_len;
+       p->vfp = fb->lower_margin;
+
+       p->invert_pxl_clk = !!(fb->sync & FB_SYNC_CLK_LAT_FALL);
+}
+
+void lcd_panel_disable(void)
+{
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX48_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX48_LCD_PWR_GPIO, 0);
+               gpio_set_value(TX48_LCD_RST_GPIO, 0);
+       }
+}
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = &tx48_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+
+       if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+
+       karo_fdt_move_fdt();
+
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 24:
+                                       case 16:
+                                       case 8:
+                                               color_depth = val;
+                                               break;
+
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx48_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
+               panel_info.vl_bpix = LCD_COLOR32;
+       }
+
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len)
+               / 1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000,
+               PICOS2KHZ(p->pixclock) % 1000);
+
+       if (p != &fb_mode) {
+               int ret;
+
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       tx48_set_pin_mux(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads));
+
+       if (karo_load_splashimage(0) == 0) {
+               struct da8xx_panel da8xx_panel = { };
+
+               debug("Initializing FB driver\n");
+               tx48_lcd_panel_setup(&da8xx_panel, p);
+               da8xx_video_init(&da8xx_panel, color_depth);
+
+               debug("Initializing LCD controller\n");
+               video_hw_init();
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+}
+#else
+#define lcd_enabled 0
+#endif /* CONFIG_LCD */
+
+static void stk5_board_init(void)
+{
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       tx48_set_pin_mux(stk5_pads, ARRAY_SIZE(stk5_pads));
+}
+
+static void stk5v3_board_init(void)
+{
+       stk5_board_init();
+}
+
+static void stk5v5_board_init(void)
+{
+       stk5_board_init();
+
+       gpio_request_array(stk5v5_gpios, ARRAY_SIZE(stk5v5_gpios));
+       tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
+}
+
+/* called with default environment! */
+int board_init(void)
+{
+       int i;
+
+       /* mach type passed to kernel */
+#ifdef CONFIG_OF_LIBFDT
+       gd->bd->bi_arch_number = -1;
+#endif
+       /* address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+
+       if (ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               if (prm_rstst & PRM_RSTST_WDT1_RST)
+                       printf("WDOG RESET detected\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+       }
+
+       gpio_request_array(tx48_gpios, ARRAY_SIZE(tx48_gpios));
+       tx48_set_pin_mux(tx48_pads, ARRAY_SIZE(tx48_pads));
+
+       for (i = 0; i < ARRAY_SIZE(tx48_gpios); i++) {
+               int gpio = tx48_gpios[i].gpio;
+
+               if (gpio_get_value(gpio) == 0)
+                       gpio_direction_output(gpio, 1);
+       }
+
+       tx48_set_pin_mux(tx48_pads, ARRAY_SIZE(tx48_i2c_pads));
+       return 0;
+}
+
+static void show_reset_cause(u32 prm_rstst)
+{
+       const char *dlm = "";
+
+       printf("RESET cause: ");
+       if (prm_rstst & PRM_RSTST_GLOBAL_COLD_RST) {
+               printf("%sPOR", dlm);
+               dlm = " | ";
+       }
+       if (prm_rstst & PRM_RSTST_GLOBAL_WARM_SW_RST) {
+               printf("%sSW", dlm);
+               dlm = " | ";
+       }
+       if (prm_rstst & PRM_RSTST_WDT1_RST) {
+               printf("%sWATCHDOG", dlm);
+               dlm = " | ";
+       }
+       if (prm_rstst & PRM_RSTST_EXTERNAL_WARM_RST) {
+               printf("%sWARM", dlm);
+               dlm = " | ";
+       }
+       if (prm_rstst & PRM_RSTST_ICEPICK_RST) {
+               printf("%sJTAG", dlm);
+               dlm = " | ";
+       }
+       if (*dlm == '\0')
+               printf("unknown");
+
+       printf(" RESET\n");
+}
+
+/* called with default environment! */
+int checkboard(void)
+{
+       prm_rstst = readl(PRM_RSTST);
+       show_reset_cause(prm_rstst);
+
+       printf("Board: Ka-Ro TX48-7020\n");
+
+       timer_init();
+       return 0;
+}
+
+static void tx48_set_cpu_clock(void)
+{
+       unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+       unsigned long act_cpu_clk;
+
+       if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000)
+               return;
+
+       if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+               printf("%s detected; skipping cpu clock change\n",
+                       (prm_rstst & PRM_RSTST_WDT1_RST) ?
+                       "WDOG RESET" : "<CTRL-C>");
+               return;
+       }
+
+       mpu_pll_config_val(cpu_clk);
+
+       act_cpu_clk = mpu_clk_rate();
+       if (cpu_clk * 1000000 != act_cpu_clk) {
+               printf("Failed to set CPU clock to %lu MHz; using %lu.%03lu MHz instead\n",
+                       cpu_clk, act_cpu_clk / 1000000,
+                       act_cpu_clk / 1000 % 1000);
+       } else {
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       act_cpu_clk / 1000000, act_cpu_clk / 1000 % 1000);
+       }
+}
+
+static void tx48_init_mac(void)
+{
+       uint8_t mac_addr[ETH_ALEN];
+       uint32_t mac_hi, mac_lo;
+
+       /* try reading mac address from efuse */
+       mac_lo = __raw_readl(MAC_ID0_LO);
+       mac_hi = __raw_readl(MAC_ID0_HI);
+
+       mac_addr[0] = mac_hi & 0xFF;
+       mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+       mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+       mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+       mac_addr[4] = mac_lo & 0xFF;
+       mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+
+       if (!is_valid_ether_addr(mac_addr)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+       printf("MAC addr from fuse: %pM\n", mac_addr);
+       eth_setenv_enetaddr("ethaddr", mac_addr);
+}
+
+/* called with environment from NAND or MMC */
+int board_late_init(void)
+{
+       int ret = 0;
+       const char *baseboard;
+
+       env_cleanup();
+
+       tx48_set_cpu_clock();
+
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (prm_rstst & PRM_RSTST_WDT1_RST)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
+
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               printf("Baseboard: %s\n", baseboard);
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       stk5v5_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+
+exit:
+       tx48_init_mac();
+       clear_ctrlc();
+       return ret;
+}
+
+#ifdef CONFIG_DRIVER_TI_CPSW
+static void tx48_phy_init(void)
+{
+       debug("%s: Resetting ethernet PHY\n", __func__);
+
+       gpio_direction_output(TX48_ETH_PHY_RST_GPIO, 0);
+
+       udelay(100);
+
+       /* Release nRST */
+       gpio_set_value(TX48_ETH_PHY_RST_GPIO, 1);
+
+       /* Wait for PHY internal POR signal to deassert */
+       udelay(25000);
+}
+
+static void cpsw_control(int enabled)
+{
+       /* nothing for now */
+       /* TODO : VTP was here before */
+}
+
+static struct cpsw_slave_data cpsw_slaves[] = {
+       {
+               .slave_reg_ofs  = 0x208,
+               .sliver_reg_ofs = 0xd80,
+               .phy_id         = 0,
+               .phy_if         = PHY_INTERFACE_MODE_RMII,
+       },
+};
+
+void s_init(void)
+{
+       /* Nothing to be done here */
+}
+
+static struct cpsw_platform_data cpsw_data = {
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
+       .mdio_div               = 0xff,
+       .channels               = 8,
+       .cpdma_reg_ofs          = 0x800,
+       .slaves                 = ARRAY_SIZE(cpsw_slaves),
+       .slave_data             = cpsw_slaves,
+       .ale_reg_ofs            = 0xd00,
+       .ale_entries            = 1024,
+       .host_port_reg_ofs      = 0x108,
+       .hw_stats_reg_ofs       = 0x900,
+       .mac_control            = (1 << 5) /* MIIEN */,
+       .control                = cpsw_control,
+       .gigabit_en             = 0,
+       .host_port_num          = 0,
+       .version                = CPSW_CTRL_VERSION_2,
+};
+
+int board_eth_init(bd_t *bis)
+{
+       __raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
+       __raw_writel(0x5D, GMII_SEL);
+       tx48_phy_init();
+       return cpsw_register(&cpsw_data);
+}
+#endif /* CONFIG_DRIVER_TI_CPSW */
+
+#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+int cpu_mmc_init(bd_t *bis)
+{
+       return omap_mmc_init(1, 0, 0, TX48_MMC_CD_GPIO, -1);
+}
+#endif
+
+void tx48_disable_watchdog(void)
+{
+       struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+
+       while (readl(&wdtimer->wdtwwps) & (1 << 4))
+               ;
+       writel(0xaaaa, &wdtimer->wdtwspr);
+       while (readl(&wdtimer->wdtwwps) & (1 << 4))
+               ;
+       writel(0x5555, &wdtimer->wdtwspr);
+}
+
+enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+};
+
+void show_activity(int arg)
+{
+       static int led_state = LED_STATE_INIT;
+       static ulong last;
+
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX48_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+       } else {
+               if (get_timer(last) > CONFIG_SYS_HZ) {
+                       last = get_timer(0);
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX48_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX48_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+}
+
+#ifdef CONFIG_OF_BOARD_SETUP
+#ifdef CONFIG_FDT_FIXUP_PARTITIONS
+#include <jffs2/jffs2.h>
+#include <mtd_node.h>
+static struct node_info nodes[] = {
+       { "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
+       { "ti,am3352-gpmc", MTD_DEV_TYPE_NAND, },
+};
+
+#else
+#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+#endif /* CONFIG_FDT_FIXUP_PARTITIONS */
+
+static const char *tx48_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "ti,am3359-tscadc",
+};
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+
+       ret = fdt_increase_size(blob, 4096);
+       if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
+               return ret;
+       }
+       fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+       fdt_fixup_ethernet(blob);
+
+       karo_fdt_fixup_touchpanel(blob, tx48_touchpanels,
+                               ARRAY_SIZE(tx48_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usb0", "phys", "vcc-supply");
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+
+       karo_fdt_update_fb_mode(blob, video_mode);
+
+       tx48_disable_watchdog();
+
+       if (get_cpu_rev() == 0) {
+               karo_fdt_del_prop(blob, "lltc,ltc3589-2", 0x34, "interrupts");
+               karo_fdt_del_prop(blob, "lltc,ltc3589-2", 0x34,
+                               "interrupt-parent");
+       }
+
+       return 0;
+}
+#endif /* CONFIG_OF_BOARD_SETUP */
diff --git a/board/karo/tx48/u-boot.lds b/board/karo/tx48/u-boot.lds
new file mode 100644 (file)
index 0000000..493cc55
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2004-2008 Texas Instruments
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+       . = 0x00000000;
+       .text :
+       {
+               *(.__image_copy_start)
+               CPUDIR/start.o (.text*)
+               *(.text*)
+       }
+
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+       . = ALIGN(4);
+       .data : {
+               *(.data*)
+       }
+
+       . = ALIGN(4);
+
+       . = .;
+
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+
+       . = ALIGN(4);
+       .image_copy_end :
+       {
+               *(.__image_copy_end)
+       }
+
+       .rel_dyn_start :
+       {
+               *(.__rel_dyn_start)
+       }
+
+       .rel.dyn :
+       {
+               *(.rel*)
+       }
+
+       .rel_dyn_end :
+       {
+               *(.__rel_dyn_end)
+       }
+
+       _end = .;
+
+/*
+ * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+ * __bss_base and __bss_limit are for linker only (overlay ordering)
+ */
+
+       .bss_start __rel_dyn_start (OVERLAY) : {
+               KEEP(*(.__bss_start));
+               __bss_base = .;
+       }
+
+       .bss __bss_base (OVERLAY) : {
+               *(.bss*)
+               . = ALIGN(4);
+               __bss_limit = .;
+       }
+       .bss_end __bss_limit (OVERLAY) : {
+               KEEP(*(.__bss_end));
+       }
+       /DISCARD/ : { *(.bss*) }
+       /DISCARD/ : { *(.dynstr*) }
+       /DISCARD/ : { *(.dynsym*) }
+       /DISCARD/ : { *(.dynamic*) }
+       /DISCARD/ : { *(.hash*) }
+       /DISCARD/ : { *(.plt*) }
+       /DISCARD/ : { *(.interp*) }
+       /DISCARD/ : { *(.gnu*) }
+}
diff --git a/board/karo/tx51/Kconfig b/board/karo/tx51/Kconfig
new file mode 100644 (file)
index 0000000..8f01051
--- /dev/null
@@ -0,0 +1,31 @@
+if TARGET_TX51_8XX0
+
+config SYS_BOARD
+       default "tx51"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mx5"
+
+config SYS_CONFIG_NAME
+       default "tx51-8xx0"
+
+endif
+
+if TARGET_TX51_8XX1_2
+
+config SYS_BOARD
+       default "tx51"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mx5"
+
+config SYS_CONFIG_NAME
+       default "tx51-8xx1_2"
+
+endif
diff --git a/board/karo/tx51/Makefile b/board/karo/tx51/Makefile
new file mode 100644 (file)
index 0000000..ee5627b
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y                          += tx51.o lowlevel_init.o
diff --git a/board/karo/tx51/config.mk b/board/karo/tx51/config.mk
new file mode 100644 (file)
index 0000000..8998907
--- /dev/null
@@ -0,0 +1,5 @@
+# stack is allocated below CONFIG_SYS_TEXT_BASE
+CONFIG_SYS_TEXT_BASE := 0x90100000
+
+PLATFORM_CPPFLAGS += -Werror
+LOGO_BMP = logos/karo.bmp
diff --git a/board/karo/tx51/lowlevel_init.S b/board/karo/tx51/lowlevel_init.S
new file mode 100644 (file)
index 0000000..af0f601
--- /dev/null
@@ -0,0 +1,199 @@
+#include <config.h>
+#include <configs/tx51.h>
+#include <asm/arch/imx-regs.h>
+
+#define DCDGEN(type, addr, data)  .long type, addr, data
+
+#define SDRAM_CLK              CONFIG_SYS_SDRAM_CLK
+
+#ifdef PHYS_SDRAM_2_SIZE
+#define SDRAM_SIZE             (PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE)
+#else
+#define SDRAM_SIZE             PHYS_SDRAM_1_SIZE
+#endif
+
+#define REG_ESDCTL0            0x00
+#define REG_ESDCFG0            0x04
+#define REG_ESDCTL1            0x08
+#define REG_ESDCFG1            0x0c
+#define REG_ESDMISC            0x10
+#define REG_ESDSCR             0x14
+#define REG_ESDGPR             0x34
+
+#define REG_CCGR0              0x68
+#define REG_CCGR1              0x6c
+#define REG_CCGR2              0x70
+#define REG_CCGR3              0x74
+#define REG_CCGR4              0x78
+#define REG_CCGR5              0x7c
+#define REG_CCGR6              0x80
+#define REG_CMEOR              0x84
+
+/* SDRAM timing setup */
+#define RALAT          1
+#define LHD            0
+
+#if SDRAM_SIZE <= SZ_128M
+#define RA_BITS                (13 - 11)       /* row addr bits - 11 */
+#else
+#define RA_BITS                (14 - 11)       /* row addr bits - 11 */
+#endif
+
+#define CA_BITS                (10 - 8)        /* 0-2: col addr bits - 8 3: rsrvd */
+#define DSIZ           2       /* 0: D[31..16] 1: D[15..D0] 2: D[31..0] 3: rsrvd */
+#define SREFR          3       /* 0: disabled 1-5: 2^n rows/clock *: rsrvd */
+#define SRT            0       /* 0: disabled *: 1: self refr. ... */
+#define PWDT           0       /* 0: disabled 1: precharge pwdn
+                                  2: pwdn after 64 clocks 3: pwdn after 128 clocks */
+#define ESDCTL_VAL     (0x80000000 | (SREFR << 28) | (RA_BITS << 24) | (CA_BITS << 20) | \
+                        (DSIZ << 16) | (SRT << 14) | (PWDT << 12))
+
+#define NS_TO_CK(ns)   (((ns) * SDRAM_CLK + 999) / 1000)
+
+       .macro          CK_VAL, name, clks, offs
+       .iflt           \clks - \offs
+       .set            \name, 0
+       .else
+       .set            \name, \clks - \offs
+       .endif
+       .endm
+
+       .macro          NS_VAL, name, ns, offs
+       .iflt           \ns - \offs
+       .set            \name, 0
+       .else
+       CK_VAL          \name, NS_TO_CK(\ns), \offs
+       .endif
+       .endm
+
+#if SDRAM_CLK < 200
+/* MT46H32M32LF-6 */
+NS_VAL tRFC, 125, 10   /* clks - 10 (0..15) */
+NS_VAL tXSR, 138, 25   /* clks - 25 (0..15) */
+NS_VAL tXP,   25,  1   /* clks - 1 (0..7)  */
+CK_VAL tWTR,   1,  1   /* clks - 1 (0..1)  */
+NS_VAL tRP,   18,  2   /* clks - 2 (0..3)  */
+CK_VAL tMRD,   2,  1   /* clks - 1 (0..3)  */
+NS_VAL tWR,   15,  2   /* clks - 2 (0..1)  */
+NS_VAL tRAS,  42,  1   /* clks - 1 (0..15) */
+NS_VAL tRRD,  12,  1   /* clks - 1 (0..3)  */
+NS_VAL tRCD,  18,  1   /* clks - 1 (0..7) */
+NS_VAL tRC,   60,  1   /* 0: 20 *: clks - 1 (0..15) */
+#else
+/* MT46H64M32LF-5 or -6 */
+NS_VAL tRFC,  72, 10   /* clks - 10 (0..15) */
+NS_VAL tXSR, 113, 25   /* clks - 25 (0..15) */
+CK_VAL tXP,    2,  1   /* clks - 1 (0..7)  */
+CK_VAL tWTR,   2,  1   /* clks - 1 (0..1)  */
+NS_VAL tRP,   18,  2   /* clks - 2 (0..3)  */
+CK_VAL tMRD,   2,  1   /* clks - 1 (0..3)  */
+NS_VAL tWR,   15,  2   /* clks - 2 (0..1)  */
+NS_VAL tRAS,  42,  1   /* clks - 1 (0..15) */
+NS_VAL tRRD,  12,  1   /* clks - 1 (0..3)  */
+NS_VAL tRCD,  18,  1   /* clks - 1 (0..7) */
+NS_VAL tRC,   60,  1   /* 0: 20 *: clks - 1 (0..15) */
+#endif
+
+#define ESDCFG_VAL     ((tRFC << 28) | (tXSR << 24) | (tXP << 21) | \
+                       (tWTR << 20) | (tRP << 18) | (tMRD << 16) | \
+                       (tRAS << 12) | (tRRD << 10) | (tWR << 7) | \
+                       (tRCD << 4) | (tRC << 0))
+
+#define ESDMISC_RALAT(n)       (((n) & 0x3) << 7)
+#define ESDMISC_DDR2_EN(n)     (((n) & 0x1) << 4)
+#define ESDMISC_DDR_EN(n)      (((n) & 0x1) << 3)
+#define ESDMISC_AP(n)          (((n) & 0xf) << 16)
+#define ESDMISC_VAL            (ESDMISC_AP(10) | ESDMISC_RALAT(RALAT) | \
+                               (LHD << 5) | ESDMISC_DDR2_EN(0) | ESDMISC_DDR_EN(0))
+
+app_start_addr:
+       .long   _start
+app_code_barker:
+       .long   0xB1
+app_code_csf:
+       .long   0 // 0x97f40000 - 0x1000
+dcd_ptr_ptr:
+       .long   dcd_ptr
+super_root_key:
+       .long   0 // hab_super_root_key
+dcd_ptr:
+       .long   dcd_data
+app_dest_ptr:
+       .long   CONFIG_SYS_TEXT_BASE
+dcd_data:
+       .long   0xB17219E9   // Fixed. can't change.
+dcd_len:
+       .long   dcd_end - dcd_start
+dcd_start:
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDCTL0, 0x80000000)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x04008008)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x00008010)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x00008010)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x00338018)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDCTL0, ESDCTL_VAL)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDCFG0, ESDCFG_VAL)
+#ifdef RAM_BANK1_SIZE
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDCTL1, ESDCTL_VAL)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDCFG1, ESDCFG_VAL)
+#endif
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDGPR, 0x00020000)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDMISC, ESDMISC_VAL)
+       DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x00000000)
+
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x508, 0x000020e0) @ EIM_SDBA2
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x50c, 0x000020e1) @ EIM_SDODT1
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x510, 0x000020e1) @ EIM_SDODT0
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x820, 0x00000040) @ (Bit6 PUE) GRP_DDRPKS
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x82c, 0x00000000) @ (Bit[1..2] DSE D[24..31]) GRP_DRAM_B4 DFT: 0x4
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x830, 0x00000000) @ (Bit9 DDR_INPUT A[0..14] CAS CS[0..1] RAS SDCKE[0..1]
+                                                       @  SDWE SDBA[0..1]) GRP_INDDR
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x838, 0x00000080) @ (Bit7 PKE D[0..31]) GRP_PKEDDR
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x83c, 0x00000000) @ (Bit[1..2] DSE A[0..7]) GRP_DDR_A0 DFT: 0x4
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x848, 0x00000000) @ (Bit[1..2] DSE A[8..14] SDBA[0..2]) GRP_DDR_A1
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x84c, 0x00000020) @ (Bit[4..5] PUS A[0..14] CAS RAS SDBA[0..1]) GRP_DDRAPUS
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x85c, 0x00000000) @ (Bit8 HYS D[0..7]) GRP_HYSDDR0
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x864, 0x00000000) @ (Bit8 HYS D[8..15]) GRP_HYSDDR1
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x86c, 0x00000000) @ (Bit8 HYS D[16..23]) GRP_HYSDDR2
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x870, 0x00002000) @ (Bit13 A[0..14] CAS CS[0..1] D[0..31] DQM[0..3] RAS
+                                                       @  SDCKE[0..1] SDCLK SDQS[0..3] SDWE SDBA[0..2]
+                                                       @  SDODT[0..1]) GRP_HVDDR
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x874, 0x00000000) @ (Bit8 HYS D[24..31]) GRP_HYSDDR3
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x878, 0x00000001) @ (Bit0 SRE D[0..7]) GRP_SR_B0
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x87c, 0x00000040) @ (Bit6 PUE A[0..14] CAS RAS SDBA[0..1]) GRP_DDRAPKS
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x880, 0x00000001) @ (Bit0 SRE D[8..15]) GRP_SR_B1
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x884, 0x00000020) @ (Bit[4..5] PUS D[0..31]) GRP_DDRPUS
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x88c, 0x00000001) @ (Bit0 SRE D[16..23]) GRP_SR_B2
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x890, 0x00000080) @ (Bit7 PKE A[0..14] CAS RAS SDBA[0..1]) GRP_PKEADDR
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x89c, 0x00000001) @ (Bit0 SRE D[24..31]) GRP_SR_B4
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x8a0, 0x00000000) @ (Bit9 DDR_INPUT D[0..31] DQM[0..3]) GRP_INMODE1
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x8a4, 0x00000000) @ (Bit[1..2] DSE D[0..7]) GRP_DRAM_B0 DFT: 0x4
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x8ac, 0x00000000) @ (Bit[1..2] DSE D[8..15]) GRP_DRAM_B1 DFT: 0x4
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x8b0, 0x00000001) @ (Bit0 SRE A[0..7]) GRP_SR_A0
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x8b8, 0x00000000) @ (Bit[1..2] DSE D[16..23]) GRP_DRAM_B2 DFT: 0x4
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x8bc, 0x00000001) @ (Bit0 SRE A[8..14] SDBA[0..2]) GRP_SR_A1
+
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x4e4, 0x2000)     @ NANDF_WE_B
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x4e8, 0x2000)     @ NANDF_RE_B
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x4ec, 0x2000)     @ NANDF_ALE
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x4f0, 0x2000)     @ NANDF_CLE
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x4f4, 0x2000)     @ NANDF_WP_B
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x4f8, 0x2000)     @ NANDF_RB0
+
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x518, 0x0084)     @ NANDF_CS0
+
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x538, 0x20e0)     @ NANDF_RDY_INT
+
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x55c, 0x20a4)     @ NANDF_D7
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x560, 0x20a4)     @ NANDF_D6
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x564, 0x20a4)     @ NANDF_D5
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x568, 0x20a4)     @ NANDF_D4
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x56c, 0x20a4)     @ NANDF_D3
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x570, 0x20a4)     @ NANDF_D2
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x574, 0x20a4)     @ NANDF_D1
+       DCDGEN(4, IOMUXC_BASE_ADDR + 0x578, 0x20a4)     @ NANDF_D0
+dcd_end:
+       .ifgt   dcd_end - dcd_start - 60 * 12
+       .error "DCD too large!"
+       .endif
+image_len:
+       .long   CONFIG_U_BOOT_IMG_SIZE
diff --git a/board/karo/tx51/tx51.c b/board/karo/tx51/tx51.c
new file mode 100644 (file)
index 0000000..ec09951
--- /dev/null
@@ -0,0 +1,1139 @@
+/*
+ * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
+ * based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <lcd.h>
+#include <netdev.h>
+#include <mmc.h>
+#include <fsl_esdhc.h>
+#include <video_fb.h>
+#include <ipu.h>
+#include <mxcfb.h>
+#include <linux/fb.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/iomux-mx51.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/sys_proto.h>
+
+#include "../common/karo.h"
+
+#define TX51_FEC_RST_GPIO      IMX_GPIO_NR(2, 14)
+#define TX51_FEC_PWR_GPIO      IMX_GPIO_NR(1, 3)
+#define TX51_FEC_INT_GPIO      IMX_GPIO_NR(3, 18)
+#define TX51_LED_GPIO          IMX_GPIO_NR(4, 10)
+
+#define TX51_LCD_PWR_GPIO      IMX_GPIO_NR(4, 14)
+#define TX51_LCD_RST_GPIO      IMX_GPIO_NR(4, 13)
+#define TX51_LCD_BACKLIGHT_GPIO        IMX_GPIO_NR(1, 2)
+
+#define TX51_RESET_OUT_GPIO    IMX_GPIO_NR(2, 15)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define IOMUX_SION             IOMUX_PAD(0, 0, IOMUX_CONFIG_SION, 0, 0, 0)
+
+#define FEC_PAD_CTRL           MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
+                                       PAD_CTL_SRE_FAST)
+#define FEC_PAD_CTRL2          MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_SRE_FAST)
+#define GPIO_PAD_CTRL          MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP)
+
+static iomux_v3_cfg_t tx51_pads[] = {
+       /* NAND flash pads are set up in lowlevel_init.S */
+
+       /* RESET_OUT */
+       MX51_PAD_EIM_A21__GPIO2_15 | GPIO_PAD_CTRL,
+
+       /* UART pads */
+#if CONFIG_MXC_UART_BASE == UART1_BASE
+       MX51_PAD_UART1_RXD__UART1_RXD,
+       MX51_PAD_UART1_TXD__UART1_TXD,
+       MX51_PAD_UART1_RTS__UART1_RTS,
+       MX51_PAD_UART1_CTS__UART1_CTS,
+#endif
+#if CONFIG_MXC_UART_BASE == UART2_BASE
+       MX51_PAD_UART2_RXD__UART2_RXD,
+       MX51_PAD_UART2_TXD__UART2_TXD,
+       MX51_PAD_EIM_D26__UART2_RTS,
+       MX51_PAD_EIM_D25__UART2_CTS,
+#endif
+#if CONFIG_MXC_UART_BASE == UART3_BASE
+       MX51_PAD_UART3_RXD__UART3_RXD,
+       MX51_PAD_UART3_TXD__UART3_TXD,
+       MX51_PAD_EIM_D18__UART3_RTS,
+       MX51_PAD_EIM_D17__UART3_CTS,
+#endif
+       /* internal I2C */
+       MX51_PAD_I2C1_DAT__GPIO4_17 | IOMUX_SION,
+       MX51_PAD_I2C1_CLK__GPIO4_16 | IOMUX_SION,
+
+       /* FEC PHY GPIO functions */
+       MX51_PAD_GPIO1_3__GPIO1_3 | GPIO_PAD_CTRL,    /* PHY POWER */
+       MX51_PAD_EIM_A20__GPIO2_14 | GPIO_PAD_CTRL,   /* PHY RESET */
+       MX51_PAD_NANDF_CS2__GPIO3_18 | GPIO_PAD_CTRL, /* PHY INT */
+
+       /* FEC functions */
+       MX51_PAD_NANDF_CS3__FEC_MDC | FEC_PAD_CTRL,
+       MX51_PAD_EIM_EB2__FEC_MDIO | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_D11__FEC_RX_DV | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_CS4__FEC_RX_ER | FEC_PAD_CTRL2,
+       MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK | FEC_PAD_CTRL2,
+       MX51_PAD_NANDF_CS7__FEC_TX_EN | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_D8__FEC_TDATA0 | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_CS4__FEC_TDATA1 | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_CS5__FEC_TDATA2 | FEC_PAD_CTRL,
+       MX51_PAD_NANDF_CS6__FEC_TDATA3 | FEC_PAD_CTRL,
+
+       /* strap pins for PHY configuration */
+       MX51_PAD_NANDF_RB3__GPIO3_11 | GPIO_PAD_CTRL, /* RX_CLK/REGOFF */
+       MX51_PAD_NANDF_D9__GPIO3_31 | GPIO_PAD_CTRL,  /* RXD0/Mode0 */
+       MX51_PAD_EIM_EB3__GPIO2_23 | GPIO_PAD_CTRL,   /* RXD1/Mode1 */
+       MX51_PAD_EIM_CS2__GPIO2_27 | GPIO_PAD_CTRL,   /* RXD2/Mode2 */
+       MX51_PAD_EIM_CS3__GPIO2_28 | GPIO_PAD_CTRL,   /* RXD3/nINTSEL */
+       MX51_PAD_NANDF_RB2__GPIO3_10 | GPIO_PAD_CTRL, /* COL/RMII/CRSDV */
+       MX51_PAD_EIM_CS5__GPIO2_30 | GPIO_PAD_CTRL,   /* CRS/PHYAD4 */
+
+       /* unusable pins on TX51 */
+       MX51_PAD_GPIO1_0__GPIO1_0,
+       MX51_PAD_GPIO1_1__GPIO1_1,
+};
+
+static const struct gpio tx51_gpios[] = {
+       /* RESET_OUT */
+       { TX51_RESET_OUT_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "RESET_OUT", },
+
+       /* FEC PHY control GPIOs */
+       { TX51_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC POWER", }, /* PHY POWER */
+       { TX51_FEC_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC RESET", }, /* PHY RESET */
+       { TX51_FEC_INT_GPIO, GPIOFLAG_INPUT, "FEC PHY INT", },      /* PHY INT (TX_ER) */
+
+       /* FEC PHY strap pins */
+       { IMX_GPIO_NR(3, 11), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY REGOFF", },  /* RX_CLK/REGOFF */
+       { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY MODE0", },   /* RXD0/Mode0 */
+       { IMX_GPIO_NR(2, 23), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY MODE1", },   /* RXD1/Mode1 */
+       { IMX_GPIO_NR(2, 27), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY MODE2", },   /* RXD2/Mode2 */
+       { IMX_GPIO_NR(2, 28), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY nINTSEL", }, /* RXD3/nINTSEL */
+       { IMX_GPIO_NR(3, 10), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY RMII", },         /* COL/RMII/CRSDV */
+       { IMX_GPIO_NR(2, 30), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY PHYAD4", },  /* CRS/PHYAD4 */
+
+       /* module internal I2C bus */
+       { IMX_GPIO_NR(4, 17), GPIOFLAG_INPUT, "I2C1 SDA", },
+       { IMX_GPIO_NR(4, 16), GPIOFLAG_INPUT, "I2C1 SCL", },
+
+       /* Unconnected pins */
+       { IMX_GPIO_NR(1, 0), GPIOFLAG_OUTPUT_INIT_LOW, "N/C", },
+       { IMX_GPIO_NR(1, 1), GPIOFLAG_OUTPUT_INIT_LOW, "N/C", },
+};
+
+/*
+ * Functions
+ */
+/* placed in section '.data' to prevent overwriting relocation info
+ * overlayed with bss
+ */
+static u32 wrsr __attribute__((section(".data")));
+
+#define WRSR_POR       (1 << 4)
+#define WRSR_TOUT      (1 << 1)
+#define WRSR_SFTW      (1 << 0)
+
+static void print_reset_cause(void)
+{
+       struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+       void __iomem *wdt_base = (void __iomem *)WDOG1_BASE_ADDR;
+       u32 srsr;
+       char *dlm = "";
+
+       printf("Reset cause: ");
+
+       srsr = readl(&src_regs->srsr);
+       wrsr = readw(wdt_base + 4);
+
+       if (wrsr & WRSR_POR) {
+               printf("%sPOR", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00004) {
+               printf("%sCSU", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00008) {
+               printf("%sIPP USER", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00010) {
+               if (wrsr & WRSR_SFTW) {
+                       printf("%sSOFT", dlm);
+                       dlm = " | ";
+               }
+               if (wrsr & WRSR_TOUT) {
+                       printf("%sWDOG", dlm);
+                       dlm = " | ";
+               }
+       }
+       if (srsr & 0x00020) {
+               printf("%sJTAG HIGH-Z", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00040) {
+               printf("%sJTAG SW", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x10000) {
+               printf("%sWARM BOOT", dlm);
+               dlm = " | ";
+       }
+       if (dlm[0] == '\0')
+               printf("unknown");
+
+       printf("\n");
+}
+
+static void tx51_print_cpuinfo(void)
+{
+       u32 cpurev;
+
+       cpurev = get_cpu_rev();
+
+       printf("CPU:   Freescale i.MX51 rev%d.%d at %d MHz\n",
+               (cpurev & 0x000F0) >> 4,
+               (cpurev & 0x0000F) >> 0,
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+
+       print_reset_cause();
+}
+
+int board_early_init_f(void)
+{
+       struct mxc_ccm_reg *ccm_regs = (void *)CCM_BASE_ADDR;
+
+       gpio_request_array(tx51_gpios, ARRAY_SIZE(tx51_gpios));
+       imx_iomux_v3_setup_multiple_pads(tx51_pads, ARRAY_SIZE(tx51_pads));
+
+       writel(0x77777777, AIPS1_BASE_ADDR + 0x00);
+       writel(0x77777777, AIPS1_BASE_ADDR + 0x04);
+
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x40);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x44);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x48);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x4c);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x50);
+
+       writel(0x77777777, AIPS2_BASE_ADDR + 0x00);
+       writel(0x77777777, AIPS2_BASE_ADDR + 0x04);
+
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x40);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x44);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x48);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x4c);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x50);
+
+       writel(0xffcfffff, &ccm_regs->CCGR0);
+       writel(0x003fffff, &ccm_regs->CCGR1);
+       writel(0x030c003c, &ccm_regs->CCGR2);
+       writel(0x000000ff, &ccm_regs->CCGR3);
+       writel(0x00000000, &ccm_regs->CCGR4);
+       writel(0x003fc003, &ccm_regs->CCGR5);
+       writel(0x00000000, &ccm_regs->CCGR6);
+       writel(0x00000000, &ccm_regs->cmeor);
+#ifdef CONFIG_CMD_BOOTCE
+       /* WinCE fails to enable these clocks */
+       writel(readl(&ccm_regs->CCGR2) | 0x0c000000, &ccm_regs->CCGR2); /* usboh3_ipg_ahb */
+       writel(readl(&ccm_regs->CCGR4) | 0x30000000, &ccm_regs->CCGR4); /* srtc */
+       writel(readl(&ccm_regs->CCGR6) | 0x00000300, &ccm_regs->CCGR6); /* emi_garb */
+#endif
+       return 0;
+}
+
+int board_init(void)
+{
+       /* Address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
+
+       if (ctrlc() || (wrsr & WRSR_TOUT)) {
+               if (wrsr & WRSR_TOUT)
+                       printf("WDOG RESET detected\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+               return 1;
+       }
+       return 0;
+}
+
+int dram_init(void)
+{
+       int ret;
+
+       /* dram_init must store complete ramsize in gd->ram_size */
+       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+                               PHYS_SDRAM_1_SIZE);
+
+       ret = mxc_set_clock(CONFIG_SYS_MX5_HCLK,
+               CONFIG_SYS_SDRAM_CLK, MXC_DDR_CLK);
+       if (ret)
+               printf("%s: Failed to set DDR clock to %u MHz: %d\n", __func__,
+                       CONFIG_SYS_SDRAM_CLK, ret);
+       else
+               debug("%s: DDR clock set to %u.%03u MHz (desig.: %u.000 MHz)\n",
+                       __func__, mxc_get_clock(MXC_DDR_CLK) / 1000000,
+                       mxc_get_clock(MXC_DDR_CLK) / 1000 % 1000,
+                       CONFIG_SYS_SDRAM_CLK);
+       return ret;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1,
+                       PHYS_SDRAM_1_SIZE);
+#if CONFIG_NR_DRAM_BANKS > 1
+       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+       gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
+                       PHYS_SDRAM_2_SIZE);
+#endif
+}
+
+#ifdef CONFIG_CMD_MMC
+static const iomux_v3_cfg_t mmc0_pads[] = {
+       MX51_PAD_SD1_CMD__SD1_CMD,
+       MX51_PAD_SD1_CLK__SD1_CLK,
+       MX51_PAD_SD1_DATA0__SD1_DATA0,
+       MX51_PAD_SD1_DATA1__SD1_DATA1,
+       MX51_PAD_SD1_DATA2__SD1_DATA2,
+       MX51_PAD_SD1_DATA3__SD1_DATA3,
+       /* SD1 CD */
+       MX51_PAD_DISPB2_SER_RS__GPIO3_8 | GPIO_PAD_CTRL,
+};
+
+static const iomux_v3_cfg_t mmc1_pads[] = {
+       MX51_PAD_SD2_CMD__SD2_CMD,
+       MX51_PAD_SD2_CLK__SD2_CLK,
+       MX51_PAD_SD2_DATA0__SD2_DATA0,
+       MX51_PAD_SD2_DATA1__SD2_DATA1,
+       MX51_PAD_SD2_DATA2__SD2_DATA2,
+       MX51_PAD_SD2_DATA3__SD2_DATA3,
+       /* SD2 CD */
+       MX51_PAD_DISPB2_SER_DIO__GPIO3_6 | GPIO_PAD_CTRL,
+};
+
+static struct tx51_esdhc_cfg {
+       const iomux_v3_cfg_t *pads;
+       int num_pads;
+       struct fsl_esdhc_cfg cfg;
+       int cd_gpio;
+} tx51_esdhc_cfg[] = {
+       {
+               .pads = mmc0_pads,
+               .num_pads = ARRAY_SIZE(mmc0_pads),
+               .cfg = {
+                       .esdhc_base = (void __iomem *)MMC_SDHC1_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(3, 8),
+       },
+       {
+               .pads = mmc1_pads,
+               .num_pads = ARRAY_SIZE(mmc1_pads),
+               .cfg = {
+                       .esdhc_base = (void __iomem *)MMC_SDHC2_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(3, 6),
+       },
+};
+
+static inline struct tx51_esdhc_cfg *to_tx51_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
+{
+       return container_of(cfg, struct tx51_esdhc_cfg, cfg);
+}
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct tx51_esdhc_cfg *cfg = to_tx51_esdhc_cfg(mmc->priv);
+
+       if (cfg->cd_gpio < 0)
+               return cfg->cd_gpio;
+
+       debug("SD card %d is %spresent\n",
+               cfg - tx51_esdhc_cfg,
+               gpio_get_value(cfg->cd_gpio) ? "NOT " : "");
+       return !gpio_get_value(cfg->cd_gpio);
+}
+
+int board_mmc_init(bd_t *bis)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(tx51_esdhc_cfg); i++) {
+               struct mmc *mmc;
+               struct tx51_esdhc_cfg *cfg = &tx51_esdhc_cfg[i];
+               int ret;
+
+               imx_iomux_v3_setup_multiple_pads(cfg->pads,
+                                               cfg->num_pads);
+               cfg->cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+
+               ret = gpio_request_one(cfg->cd_gpio,
+                               GPIOFLAG_INPUT, "MMC CD");
+               if (ret) {
+                       printf("Error %d requesting GPIO%d_%d\n",
+                               ret, cfg->cd_gpio / 32, cfg->cd_gpio % 32);
+                       continue;
+               }
+
+               debug("%s: Initializing MMC slot %d\n", __func__, i);
+               fsl_esdhc_initialize(bis, &cfg->cfg);
+
+               mmc = find_mmc_device(i);
+               if (mmc == NULL)
+                       continue;
+               if (board_mmc_getcd(mmc) > 0)
+                       mmc_init(mmc);
+       }
+       return 0;
+}
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_FEC_MXC
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+       int i;
+       struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
+       struct fuse_bank *bank = &iim->bank[1];
+       struct fuse_bank1_regs *fuse = (struct fuse_bank1_regs *)bank->fuse_regs;
+
+       if (dev_id > 0)
+               return;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               mac[ETH_ALEN - i - 1] = readl(&fuse->mac_addr[i]);
+}
+
+static iomux_v3_cfg_t tx51_fec_pads[] = {
+       /* reconfigure strap pins for FEC function */
+       MX51_PAD_NANDF_RB3__FEC_RX_CLK | FEC_PAD_CTRL2,
+       MX51_PAD_NANDF_D9__FEC_RDATA0 | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_EB3__FEC_RDATA1 | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_CS2__FEC_RDATA2 | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_CS3__FEC_RDATA3 | FEC_PAD_CTRL2,
+       MX51_PAD_NANDF_RB2__FEC_COL | FEC_PAD_CTRL2,
+       MX51_PAD_EIM_CS5__FEC_CRS | FEC_PAD_CTRL,
+};
+
+/* take bit 4 of PHY address from configured PHY address or
+ * set it to 0 if PHYADDR is -1 (probe for PHY)
+ */
+#define PHYAD4 ((CONFIG_FEC_MXC_PHYADDR >> 4) & !(CONFIG_FEC_MXC_PHYADDR >> 5))
+
+static struct gpio tx51_fec_gpios[] = {
+       { TX51_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY POWER", },
+       { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY Mode0", },    /* RXD0/Mode0 */
+       { IMX_GPIO_NR(2, 23), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY Mode1", },    /* RXD1/Mode1 */
+       { IMX_GPIO_NR(2, 27), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY Mode2", },    /* RXD2/Mode2 */
+       { IMX_GPIO_NR(2, 28), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY nINTSEL", },  /* RXD3/nINTSEL */
+#if PHYAD4
+       { IMX_GPIO_NR(2, 30), GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY PHYAD4", }, /* CRS/PHYAD4 */
+#else
+       { IMX_GPIO_NR(2, 30), GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY PHYAD4", }, /* CRS/PHYAD4 */
+#endif
+};
+
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       /* Power up the external phy and assert strap options */
+       gpio_request_array(tx51_fec_gpios, ARRAY_SIZE(tx51_fec_gpios));
+
+       /* delay at least 21ms for the PHY internal POR signal to deassert */
+       udelay(22000);
+
+       /* Deassert RESET to the external phy */
+       gpio_set_value(TX51_FEC_RST_GPIO, 1);
+
+       /* Without this delay the PHY won't work, though nothing in
+        * the datasheets suggests that it should be necessary!
+        */
+       udelay(400);
+       imx_iomux_v3_setup_multiple_pads(tx51_fec_pads,
+                                       ARRAY_SIZE(tx51_fec_pads));
+
+       ret = cpu_eth_init(bis);
+       if (ret)
+               printf("cpu_eth_init() failed: %d\n", ret);
+
+       return ret;
+}
+#endif /* CONFIG_FEC_MXC */
+
+enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+};
+
+void show_activity(int arg)
+{
+       static int led_state = LED_STATE_INIT;
+       static ulong last;
+
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX51_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+       } else {
+               if (get_timer(last) > CONFIG_SYS_HZ) {
+                       last = get_timer(0);
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX51_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX51_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+}
+
+static const iomux_v3_cfg_t stk5_pads[] = {
+       /* SW controlled LED on STK5 baseboard */
+       MX51_PAD_CSI2_D13__GPIO4_10 | GPIO_PAD_CTRL,
+
+       /* USB PHY reset */
+       MX51_PAD_GPIO1_4__GPIO1_4 | GPIO_PAD_CTRL,
+       /* USBOTG OC */
+       MX51_PAD_GPIO1_6__GPIO1_6 | GPIO_PAD_CTRL,
+       /* USB PHY clock enable */
+       MX51_PAD_GPIO1_7__GPIO1_7 | GPIO_PAD_CTRL,
+       /* USBH1 VBUS enable */
+       MX51_PAD_GPIO1_8__GPIO1_8 | GPIO_PAD_CTRL,
+       /* USBH1 OC */
+       MX51_PAD_GPIO1_9__GPIO1_9 | GPIO_PAD_CTRL,
+};
+
+static const struct gpio stk5_gpios[] = {
+       { TX51_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
+
+       { IMX_GPIO_NR(1, 4), GPIOFLAG_OUTPUT_INIT_LOW, "ULPI PHY clk enable", },
+       { IMX_GPIO_NR(1, 6), GPIOFLAG_INPUT, "USBOTG OC", },
+       { IMX_GPIO_NR(1, 7), GPIOFLAG_OUTPUT_INIT_LOW, "ULPI PHY reset", },
+       { IMX_GPIO_NR(1, 8), GPIOFLAG_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
+       { IMX_GPIO_NR(1, 9), GPIOFLAG_INPUT, "USBH1 OC", },
+};
+
+#ifdef CONFIG_LCD
+static u16 tx51_cmap[256];
+vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1600,
+       .vl_row = 1200,
+
+       .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx51_cmap,
+};
+
+static struct fb_videomode tx51_fb_modes[] = {
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+};
+
+static int lcd_enabled = 1;
+static int lcd_bl_polarity;
+
+static int lcd_backlight_polarity(void)
+{
+       return lcd_bl_polarity;
+}
+
+void lcd_enable(void)
+{
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+
+       if (lcd_enabled) {
+               karo_load_splashimage(1);
+
+               debug("Switching LCD on\n");
+               gpio_set_value(TX51_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX51_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX51_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+}
+
+void lcd_disable(void)
+{
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               ipuv3_fb_shutdown();
+       }
+}
+
+void lcd_panel_disable(void)
+{
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX51_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX51_LCD_RST_GPIO, 0);
+               gpio_set_value(TX51_LCD_PWR_GPIO, 0);
+       }
+}
+
+static const iomux_v3_cfg_t stk5_lcd_pads[] = {
+       /* LCD RESET */
+       MX51_PAD_CSI2_VSYNC__GPIO4_13,
+       /* LCD POWER_ENABLE */
+       MX51_PAD_CSI2_HSYNC__GPIO4_14,
+       /* LCD Backlight (PWM) */
+       MX51_PAD_GPIO1_2__GPIO1_2,
+
+       /* Display */
+       MX51_PAD_DISP1_DAT0__DISP1_DAT0,
+       MX51_PAD_DISP1_DAT1__DISP1_DAT1,
+       MX51_PAD_DISP1_DAT2__DISP1_DAT2,
+       MX51_PAD_DISP1_DAT3__DISP1_DAT3,
+       MX51_PAD_DISP1_DAT4__DISP1_DAT4,
+       MX51_PAD_DISP1_DAT5__DISP1_DAT5,
+       MX51_PAD_DISP1_DAT6__DISP1_DAT6,
+       MX51_PAD_DISP1_DAT7__DISP1_DAT7,
+       MX51_PAD_DISP1_DAT8__DISP1_DAT8,
+       MX51_PAD_DISP1_DAT9__DISP1_DAT9,
+       MX51_PAD_DISP1_DAT10__DISP1_DAT10,
+       MX51_PAD_DISP1_DAT11__DISP1_DAT11,
+       MX51_PAD_DISP1_DAT12__DISP1_DAT12,
+       MX51_PAD_DISP1_DAT13__DISP1_DAT13,
+       MX51_PAD_DISP1_DAT14__DISP1_DAT14,
+       MX51_PAD_DISP1_DAT15__DISP1_DAT15,
+       MX51_PAD_DISP1_DAT16__DISP1_DAT16,
+       MX51_PAD_DISP1_DAT17__DISP1_DAT17,
+       MX51_PAD_DISP1_DAT18__DISP1_DAT18,
+       MX51_PAD_DISP1_DAT19__DISP1_DAT19,
+       MX51_PAD_DISP1_DAT20__DISP1_DAT20,
+       MX51_PAD_DISP1_DAT21__DISP1_DAT21,
+       MX51_PAD_DISP1_DAT22__DISP1_DAT22,
+       MX51_PAD_DISP1_DAT23__DISP1_DAT23,
+       MX51_PAD_DI1_PIN2__DI1_PIN2, /* HSYNC */
+       MX51_PAD_DI1_PIN3__DI1_PIN3, /* VSYNC */
+};
+
+static const struct gpio stk5_lcd_gpios[] = {
+       { TX51_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
+       { TX51_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
+       { TX51_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+};
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = &tx51_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+       int pix_fmt;
+       int lcd_bus_width;
+       ipu_di_clk_parent_t di_clk_parent = DI_PCLK_PLL3;
+       unsigned long di_clk_rate = 65000000;
+
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+
+       karo_fdt_move_fdt();
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 8:
+                                       case 16:
+                                       case 24:
+                                       case 32:
+                                               color_depth = val;
+                                               break;
+
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx51_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
+               panel_info.vl_bpix = LCD_COLOR32;
+       }
+
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
+                               1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000,
+               PICOS2KHZ(p->pixclock) % 1000);
+
+       if (p != &fb_mode) {
+               int ret;
+
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
+                                       ARRAY_SIZE(stk5_lcd_pads));
+
+       lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24);
+       switch (lcd_bus_width) {
+       case 24:
+               pix_fmt = IPU_PIX_FMT_RGB24;
+               break;
+
+       case 18:
+               pix_fmt = IPU_PIX_FMT_RGB666;
+               break;
+
+       case 16:
+               pix_fmt = IPU_PIX_FMT_RGB565;
+               break;
+
+       default:
+               lcd_enabled = 0;
+               printf("Invalid LCD bus width: %d\n", lcd_bus_width);
+               return;
+       }
+       if (karo_load_splashimage(0) == 0) {
+               int ret;
+               struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)MXC_CCM_BASE;
+               u32 ccgr4 = readl(&ccm_regs->CCGR4);
+
+               /* MIPI HSC clock is required for initialization */
+               writel(ccgr4 | (3 << 12), &ccm_regs->CCGR4);
+
+               gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3DEX;
+
+               debug("Initializing LCD controller\n");
+               ret = ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
+               writel(ccgr4 & ~(3 << 12), &ccm_regs->CCGR4);
+               if (ret) {
+                       printf("Failed to initialize FB driver: %d\n", ret);
+                       lcd_enabled = 0;
+               }
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+}
+#else
+#define lcd_enabled 0
+#endif /* CONFIG_LCD */
+
+static void stk5_board_init(void)
+{
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+}
+
+static void stk5v3_board_init(void)
+{
+       stk5_board_init();
+}
+
+static void tx51_set_cpu_clock(void)
+{
+       unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+
+       if (had_ctrlc() || (wrsr & WRSR_TOUT))
+               return;
+
+       if (cpu_clk == 0 || cpu_clk == mxc_get_clock(MXC_ARM_CLK) / 1000000)
+               return;
+
+       if (mxc_set_clock(CONFIG_SYS_MX5_HCLK, cpu_clk, MXC_ARM_CLK) == 0) {
+               cpu_clk = mxc_get_clock(MXC_ARM_CLK);
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       cpu_clk / 1000000, cpu_clk / 1000 % 1000);
+       } else {
+               printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk);
+       }
+}
+
+static void tx51_init_mac(void)
+{
+       u8 mac[ETH_ALEN];
+
+       imx_get_mac_from_fuse(0, mac);
+       if (!is_valid_ether_addr(mac)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+
+       printf("MAC addr from fuse: %pM\n", mac);
+       eth_setenv_enetaddr("ethaddr", mac);
+}
+
+int board_late_init(void)
+{
+       int ret = 0;
+       const char *baseboard;
+
+       env_cleanup();
+
+       tx51_set_cpu_clock();
+
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (wrsr & WRSR_TOUT)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
+
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+
+       printf("Baseboard: %s\n", baseboard);
+
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       printf("ERROR: Baseboard '%s' incompatible with TX51 module!\n",
+                               baseboard);
+                       stk5v3_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+
+exit:
+       tx51_init_mac();
+
+       gpio_set_value(TX51_RESET_OUT_GPIO, 1);
+       clear_ctrlc();
+       return ret;
+}
+
+int checkboard(void)
+{
+       tx51_print_cpuinfo();
+#if CONFIG_NR_DRAM_BANKS > 1
+       printf("Board: Ka-Ro TX51-8xx1 | TX51-8xx2\n");
+#else
+       printf("Board: Ka-Ro TX51-8xx0\n");
+#endif
+       return 0;
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+#ifdef CONFIG_FDT_FIXUP_PARTITIONS
+#include <jffs2/jffs2.h>
+#include <mtd_node.h>
+static struct node_info nodes[] = {
+       { "fsl,imx51-nand", MTD_DEV_TYPE_NAND, },
+};
+#else
+#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+#endif
+
+static const char *tx51_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+};
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+
+       ret = fdt_increase_size(blob, 4096);
+       if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
+               return ret;
+       }
+       fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+       fdt_fixup_ethernet(blob);
+
+       karo_fdt_fixup_touchpanel(blob, tx51_touchpanels,
+                               ARRAY_SIZE(tx51_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
+       karo_fdt_update_fb_mode(blob, video_mode);
+
+       return 0;
+}
+#endif /* CONFIG_OF_BOARD_SETUP */
diff --git a/board/karo/tx51/u-boot.lds b/board/karo/tx51/u-boot.lds
new file mode 100644 (file)
index 0000000..7c9ca89
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * (C) Copyright 2012  Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+       . = 0x00000000;
+       .text :
+       {
+               *(.__image_copy_start)
+               CPUDIR/start.o (.text*)
+               . = 0x400;
+               KEEP(board/karo/tx51/lowlevel_init.o (.text*))
+               *(.text*)
+       }
+
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+       . = ALIGN(4);
+       .data : {
+               *(.data*)
+       }
+
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+
+       . = ALIGN(4);
+       .image_copy_end :
+       {
+               *(.__image_copy_end)
+       }
+
+       .rel_dyn_start :
+       {
+               *(.__rel_dyn_start)
+       }
+
+       .rel.dyn :
+       {
+               *(.rel*)
+       }
+
+       .rel_dyn_end :
+       {
+               *(.__rel_dyn_end)
+       }
+
+       _end = .;
+
+/*
+ * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+ * __bss_base and __bss_limit are for linker only (overlay ordering)
+ */
+
+       .bss_start __rel_dyn_start (OVERLAY) : {
+               KEEP(*(.__bss_start));
+               __bss_base = .;
+       }
+
+       .bss __bss_base (OVERLAY) : {
+               *(.bss*)
+               . = ALIGN(4);
+               __bss_limit = .;
+       }
+       .bss_end __bss_limit (OVERLAY) : {
+               KEEP(*(.__bss_end));
+       }
+       /DISCARD/ : { *(.bss*) }
+       /DISCARD/ : { *(.dynstr*) }
+       /DISCARD/ : { *(.dynsym*) }
+       /DISCARD/ : { *(.dynamic*) }
+       /DISCARD/ : { *(.hash*) }
+       /DISCARD/ : { *(.plt*) }
+       /DISCARD/ : { *(.interp*) }
+       /DISCARD/ : { *(.gnu*) }
+}
diff --git a/board/karo/tx53/Kconfig b/board/karo/tx53/Kconfig
new file mode 100644 (file)
index 0000000..3e6670f
--- /dev/null
@@ -0,0 +1,99 @@
+if TARGET_TX53
+
+config SYS_BOARD
+       default "tx53"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mx5"
+
+config SYS_CONFIG_NAME
+       default "tx53"
+
+config CMD_ROMUPDATE
+       bool
+
+config MX5
+       bool
+
+config MX53
+       bool
+       default y
+       select CPU_V7
+       select MX5
+
+config TX53
+       bool
+       default y
+       select CC_OPTIMIZE_LIBS_FOR_SPEED
+       select CMD_BMP if LCD
+       select CMD_BOOTCE
+       select CMD_BOOTZ
+       select CMD_CACHE
+       select CMD_I2C if I2C
+       select CMD_MEMINFO
+       select CMD_MEMTEST
+       select CMD_NAND
+       select CMD_NAND_TRIMFFS
+       select CMD_ROMUPDATE
+       select CMD_TIME
+       select DM
+       select DM_GPIO
+       select FDT_FIXUP_PARTITIONS if OF_LIBFDT
+       select GET_FEC_MAC_ADDR_FROM_IIM
+       select IMX_WATCHDOG
+       select MTD_PARTITIONS
+       select MTD_DEVICE
+       select MX53
+       select NAND
+       select NAND_MXC
+       select OF_LIBFDT
+       select OF_BOARD_SETUP
+       select PHYLIB
+       select PHY_SMSC
+       select SYS_I2C
+       select SYS_I2C_MXC
+       select SYS_NAND_USE_FLASH_BBT if NAND_MXC
+
+#
+# variables selected depending on module variant
+#
+
+config SYS_LVDS_IF
+       bool
+
+config NR_DRAM_BANKS
+       int
+       default 1
+
+choice
+       prompt "TX53 module variant"
+
+config TARGET_TX53_X030
+       bool "TX53-8030 and TX53-1030"
+
+config TARGET_TX53_X130
+       bool "TX53-8030 and TX53-1030"
+
+config TARGET_TX53_X131
+       bool "TX53-8131 and TX53-1131"
+
+config TARGET_TX53_1232
+       bool "TX53-1232
+
+endchoice
+
+choice
+       prompt "U-Boot image variant"
+
+config TX53_UBOOT
+       bool "Standard U-Boot image"
+
+config TX53_UBOOT_NOENV
+       bool "U-Boot using only built-in environment"
+
+endchoice
+
+endif
diff --git a/board/karo/tx53/Makefile b/board/karo/tx53/Makefile
new file mode 100644 (file)
index 0000000..7500ab6
--- /dev/null
@@ -0,0 +1,10 @@
+#
+# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+LDSCRIPT := $(BOARDDIR)/u-boot.lds
+
+obj-y                          += lowlevel_init.o tx53.o
+obj-$(CONFIG_CMD_ROMUPDATE)    += flash.o
diff --git a/board/karo/tx53/config.mk b/board/karo/tx53/config.mk
new file mode 100644 (file)
index 0000000..e765c3a
--- /dev/null
@@ -0,0 +1,5 @@
+# stack is allocated below CONFIG_SYS_TEXT_BASE
+CONFIG_SYS_TEXT_BASE := 0x70100000
+
+PLATFORM_CPPFLAGS += -Werror
+LOGO_BMP = logos/karo.bmp
diff --git a/board/karo/tx53/flash.c b/board/karo/tx53/flash.c
new file mode 100644 (file)
index 0000000..d6463cf
--- /dev/null
@@ -0,0 +1,565 @@
+/*
+ * Copyright (C) 2011-2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <nand.h>
+#include <errno.h>
+
+#include <linux/err.h>
+#include <jffs2/load_kernel.h>
+
+struct mx53_fcb {
+       u32 rsrvd0;
+       u32 fingerprint;
+       u32 version;
+       u32 rsrvd1[23];
+       u32 fw1_start_page;
+       u32 fw2_start_page;
+       u32 rsrvd2[2];
+       u32 dbbt_search_area;
+       u32 bb_mark_phys_offset;
+       u32 rsrvd3[11];
+       u32 bb_swap;
+       u32 bb_mark_byte;
+       u32 rsrvd4[83];
+};
+
+static nand_info_t *mtd = &nand_info[0];
+static bool doit;
+
+static inline int calc_bb_offset(struct mx53_fcb *fcb)
+{
+       int ecc_block_size = 512;
+       int ecc_size = mtd->oobsize / (mtd->writesize / ecc_block_size);
+       int bb_mark_chunk, bb_mark_chunk_offs;
+
+       bb_mark_chunk = mtd->writesize / (ecc_block_size + ecc_size);
+       bb_mark_chunk_offs = mtd->writesize % (ecc_block_size + ecc_size);
+       if (bb_mark_chunk_offs > ecc_block_size) {
+               printf("Unsupported ECC layout; BB mark resides in ECC data: %u\n",
+                       bb_mark_chunk_offs);
+               return -EINVAL;
+       }
+       printf("BB mark is in block %d offset %d\n",
+               bb_mark_chunk, bb_mark_chunk_offs);
+
+       return bb_mark_chunk * ecc_block_size + bb_mark_chunk_offs;
+}
+
+/*
+ * return number of blocks to skip for a contiguous partition
+ * of given # blocks
+ */
+static int find_contig_space(int block, int num_blocks, int max_blocks)
+{
+       int skip = 0;
+       int found = 0;
+       int last = block + max_blocks;
+
+       debug("Searching %u contiguous blocks from %d..%d\n",
+               num_blocks, block, block + max_blocks - 1);
+       for (; block < last; block++) {
+               if (nand_block_isbad(mtd, block * mtd->erasesize)) {
+                       skip += found + 1;
+                       found = 0;
+                       debug("Skipping %u blocks to %u\n",
+                               skip, block + 1);
+               } else {
+                       found++;
+                       if (found >= num_blocks) {
+                               debug("Found %u good blocks from %d..%d\n",
+                                       found, block - found + 1, block);
+                               return skip;
+                       }
+               }
+       }
+       return -ENOSPC;
+}
+
+#define offset_of(p, m)                ((void *)&(p)->m - (void *)(p))
+#define pr_fcb_val(p, n)       debug("%-24s[%02x]=%08x(%d)\n", #n, offset_of(p, n), (p)->n, (p)->n)
+
+static struct mx53_fcb *create_fcb(void *buf, int fw1_start_block,
+                               int fw2_start_block, int fw_num_blocks)
+{
+       struct mx53_fcb *fcb;
+       u32 sectors_per_block = mtd->erasesize / mtd->writesize;
+
+       fcb = buf;
+
+       memset(fcb, 0x00, sizeof(*fcb));
+       memset(fcb + 1, 0xff, mtd->erasesize - sizeof(*fcb));
+
+       strncpy((char *)&fcb->fingerprint, "FCB ", 4);
+       fcb->version = 1;
+
+       fcb->fw1_start_page = fw1_start_block * sectors_per_block;
+       pr_fcb_val(fcb, fw1_start_page);
+
+       if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
+               fcb->fw2_start_page = fw2_start_block * sectors_per_block;
+               pr_fcb_val(fcb, fw2_start_page);
+       }
+
+       return fcb;
+}
+
+static int find_fcb(void *ref, int page)
+{
+       int ret = 0;
+       struct nand_chip *chip = mtd->priv;
+       void *buf = malloc(mtd->erasesize);
+
+       if (buf == NULL) {
+               return -ENOMEM;
+       }
+       chip->select_chip(mtd, 0);
+       chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+       ret = chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
+       if (ret) {
+               printf("Failed to read FCB from page %u: %d\n", page, ret);
+               goto out;
+       }
+       if (memcmp(buf, ref, mtd->writesize) == 0) {
+               debug("Found FCB in page %u (%08x)\n",
+                       page, page * mtd->writesize);
+               ret = 1;
+       }
+out:
+       chip->select_chip(mtd, -1);
+       free(buf);
+       return ret;
+}
+
+static int write_fcb(void *buf, int block)
+{
+       int ret;
+       struct nand_chip *chip = mtd->priv;
+       int page = block * mtd->erasesize / mtd->writesize;
+
+       ret = find_fcb(buf, page);
+       if (ret > 0) {
+               printf("FCB at block %d is up to date\n", block);
+               return 0;
+       }
+
+       printf("Erasing FCB block %08x..%08x\n", block * mtd->erasesize,
+               block * mtd->erasesize + mtd->erasesize - 1);
+       if (doit) {
+               ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
+               if (ret) {
+                       printf("Failed to erase FCB block %u\n", block);
+                       return ret;
+               }
+       }
+
+       printf("Writing FCB to block %d @ %08llx\n", block,
+               (u64)block * mtd->erasesize);
+       if (doit) {
+               chip->select_chip(mtd, 0);
+               ret = chip->write_page(mtd, chip, 0, mtd->writesize,
+                               buf, 1, page, 0, 0);
+               if (ret) {
+                       printf("Failed to write FCB to block %u: %d\n", block, ret);
+               }
+               chip->select_chip(mtd, -1);
+       }
+       return ret;
+}
+
+#define chk_overlap(a,b)                               \
+       ((a##_start_block <= b##_end_block &&           \
+               a##_end_block >= b##_start_block) ||    \
+       (b##_start_block <= a##_end_block &&            \
+               b##_end_block >= a##_start_block))
+
+#define fail_if_overlap(a,b,m1,m2) do {                                        \
+       if (!doit)                                                      \
+               printf("check: %s[%lu..%lu] <> %s[%lu..%lu]\n",         \
+                       m1, a##_start_block, a##_end_block,             \
+                       m2, b##_start_block, b##_end_block);            \
+       if (a##_end_block < a##_start_block)                            \
+               printf("Invalid start/end block # for %s\n", m1);       \
+       if (b##_end_block < b##_start_block)                            \
+               printf("Invalid start/end block # for %s\n", m2);       \
+       if (chk_overlap(a, b)) {                                        \
+               printf("%s blocks %lu..%lu overlap %s in blocks %lu..%lu!\n", \
+                       m1, a##_start_block, a##_end_block,             \
+                       m2, b##_start_block, b##_end_block);            \
+               return -EINVAL;                                         \
+       }                                                               \
+} while (0)
+
+static int tx53_prog_uboot(void *addr, int start_block, int skip,
+                       size_t size, size_t max_len)
+{
+       int ret;
+       nand_erase_options_t erase_opts = { 0, };
+       size_t actual;
+       size_t prg_length = max_len - skip * mtd->erasesize;
+       int prg_start = start_block * mtd->erasesize;
+
+       erase_opts.offset = (start_block - skip) * mtd->erasesize;
+       erase_opts.length = max_len;
+       erase_opts.quiet = 1;
+
+       printf("Erasing flash @ %08llx..%08llx\n", erase_opts.offset,
+               erase_opts.offset + erase_opts.length - 1);
+       if (doit) {
+               ret = nand_erase_opts(mtd, &erase_opts);
+               if (ret) {
+                       printf("Failed to erase flash: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       printf("Programming flash @ %08x..%08x from %p\n",
+               prg_start, prg_start + size - 1, addr);
+       if (doit) {
+               actual = size;
+               ret = nand_write_skip_bad(mtd, prg_start, &actual, NULL,
+                                       prg_length, addr, WITH_DROP_FFS);
+               if (ret) {
+                       printf("Failed to program flash: %d\n", ret);
+                       return ret;
+               }
+               if (actual < size) {
+                       printf("Could only write %u of %u bytes\n", actual, size);
+                       return -EIO;
+               }
+       }
+       return 0;
+}
+
+#ifdef CONFIG_ENV_IS_IN_NAND
+#ifndef CONFIG_ENV_OFFSET_REDUND
+#define TOTAL_ENV_SIZE CONFIG_ENV_RANGE
+#else
+#define TOTAL_ENV_SIZE (CONFIG_ENV_RANGE * 2)
+#endif
+#endif
+
+int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int ret;
+       const unsigned long fcb_start_block = 0, fcb_end_block = 0;
+       int erase_size = mtd->erasesize;
+       int page_size = mtd->writesize;
+       void *buf;
+       char *load_addr;
+       char *file_size;
+       size_t size = 0;
+       void *addr = NULL;
+       struct mx53_fcb *fcb;
+       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+#ifdef CONFIG_ENV_IS_IN_NAND
+       unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
+       unsigned long env_end_block = env_start_block +
+               DIV_ROUND_UP(TOTAL_ENV_SIZE, mtd->erasesize) - 1;
+#endif
+       int optind;
+       int fw2_set = 0;
+       unsigned long fw1_start_block = 0, fw1_end_block;
+       unsigned long fw2_start_block = 0, fw2_end_block;
+       unsigned long fw_num_blocks;
+       int fw1_skip, fw2_skip;
+       unsigned long extra_blocks = 0;
+       size_t max_len1, max_len2;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       struct part_info *redund_part_info;
+       const char *uboot_part = "u-boot";
+       const char *redund_part = NULL;
+       u8 part_num;
+       u8 redund_part_num;
+
+       ret = mtdparts_init();
+       if (ret)
+               return ret;
+
+       doit = true;
+       for (optind = 1; optind < argc; optind++) {
+               char *endp;
+
+               if (strcmp(argv[optind], "-f") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       fw1_start_block = simple_strtoul(argv[optind], &endp, 0);
+                       if (*endp != '\0') {
+                               uboot_part = argv[optind];
+                               continue;
+                       }
+                       uboot_part = NULL;
+                       if (fw1_start_block >= mtd_num_blocks) {
+                               printf("Block number %lu is out of range: 0..%lu\n",
+                                       fw1_start_block, mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (strcmp(argv[optind], "-r") == 0) {
+                       fw2_set = 1;
+                       if (optind < argc - 1 && argv[optind + 1][0] != '-') {
+                               optind++;
+                               fw2_start_block = simple_strtoul(argv[optind],
+                                                               &endp, 0);
+                               if (*endp != '\0') {
+                                       redund_part = argv[optind];
+                                       continue;
+                               }
+                               if (fw2_start_block >= mtd_num_blocks) {
+                                       printf("Block number %lu is out of range: 0..%lu\n",
+                                               fw2_start_block,
+                                               mtd_num_blocks - 1);
+                                       return -EINVAL;
+                               }
+                       }
+               } else if (strcmp(argv[optind], "-e") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       extra_blocks = simple_strtoul(argv[optind], NULL, 0);
+                       if (extra_blocks >= mtd_num_blocks) {
+                               printf("Extra block count %lu is out of range: 0..%lu\n",
+                                       extra_blocks,
+                                       mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (strcmp(argv[optind], "-n") == 0) {
+                       doit = false;
+               } else if (argv[optind][0] == '-') {
+                       printf("Unrecognized option %s\n", argv[optind]);
+                       return -EINVAL;
+               } else {
+                       break;
+               }
+       }
+
+       load_addr = getenv("fileaddr");
+       file_size = getenv("filesize");
+
+       if (argc - optind < 1 && load_addr == NULL) {
+               printf("Load address not specified\n");
+               return -EINVAL;
+       }
+       if (argc - optind < 2 && file_size == NULL) {
+               if (uboot_part) {
+                       printf("WARNING: Image size not specified; overwriting whole '%s' partition\n",
+                               uboot_part);
+                       printf("This will only work, if there are no bad blocks inside this partition!\n");
+               } else {
+                       printf("ERROR: Image size must be specified\n");
+                       return -EINVAL;
+               }
+       }
+       if (argc > optind) {
+               load_addr = NULL;
+               addr = (void *)simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (argc > optind) {
+               file_size = NULL;
+               size = simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (load_addr != NULL) {
+               addr = (void *)simple_strtoul(load_addr, NULL, 16);
+               printf("Using default load address %p\n", addr);
+       }
+       if (file_size != NULL) {
+               size = simple_strtoul(file_size, NULL, 16);
+               printf("Using default file size %08x\n", size);
+       }
+       if (size > 0)
+               fw_num_blocks = DIV_ROUND_UP(size, mtd->erasesize);
+       else
+               fw_num_blocks = 0;
+
+       if (uboot_part) {
+               ret = find_dev_and_part(uboot_part, &dev, &part_num,
+                                       &part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               uboot_part, ret);
+                       return ret;
+               }
+               fw1_start_block = part_info->offset / mtd->erasesize;
+               max_len1 = part_info->size;
+               /*
+                * Skip one block, if the U-Boot image resides in the
+                * same partition as the FCB
+                */
+               if (fw1_start_block == fcb_start_block) {
+                       fw1_start_block++;
+                       max_len1 -= mtd->erasesize;
+               }
+               if (size == 0)
+                       fw_num_blocks = max_len1 / mtd->erasesize;
+       } else {
+               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       }
+
+       if (redund_part) {
+               ret = find_dev_and_part(redund_part, &dev, &redund_part_num,
+                                       &redund_part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               redund_part, ret);
+                       return ret;
+               }
+               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               max_len2 = redund_part_info->size;
+               if (fw2_start_block == fcb_start_block) {
+                       fw2_start_block++;
+                       max_len2 -= mtd->erasesize;
+               }
+               if (size == 0)
+                       fw_num_blocks = max_len2 / mtd->erasesize;
+       } else if (fw2_set) {
+               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       } else {
+               max_len2 = 0;
+       }
+
+       fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
+                               max_len1 / mtd->erasesize);
+       if (fw1_skip < 0) {
+               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%lu\n",
+                       fw_num_blocks, fw1_start_block,
+                       fw1_start_block + max_len1 / mtd->erasesize - 1);
+               if (uboot_part) {
+#ifdef CONFIG_ENV_IS_IN_NAND
+                       if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
+                               printf("Use a different partition\n");
+                       } else {
+                               printf("Increase the size of the '%s' partition\n",
+                                       uboot_part);
+                       }
+#else
+                       printf("Increase the size of the '%s' partition\n",
+                               uboot_part);
+#endif
+               } else {
+                       printf("Increase the number of spare blocks to use with the '-e' option\n");
+               }
+               return -ENOSPC;
+       }
+       if (extra_blocks)
+               fw1_end_block = fw1_start_block + fw_num_blocks + extra_blocks - 1;
+       else
+               fw1_end_block = fw1_start_block + fw_num_blocks + fw1_skip - 1;
+
+       if (fw2_set && fw2_start_block == 0)
+               fw2_start_block = fw1_end_block + 1;
+       if (fw2_start_block > 0) {
+               fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
+                                       max_len2 / mtd->erasesize);
+               if (fw2_skip < 0) {
+                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%lu\n",
+                               fw_num_blocks, fw2_start_block,
+                               fw2_start_block + max_len2 / mtd->erasesize - 1);
+                       if (redund_part) {
+                               printf("Increase the size of the '%s' partition or use a different partition\n",
+                                       redund_part);
+                       } else {
+                               printf("Increase the number of spare blocks to use with the '-e' option\n");
+                       }
+                       return -ENOSPC;
+               }
+       } else {
+               fw2_skip = 0;
+       }
+       if (extra_blocks)
+               fw2_end_block = fw2_start_block + fw_num_blocks + extra_blocks - 1;
+       else
+               fw2_end_block = fw2_start_block + fw_num_blocks + fw2_skip - 1;
+
+#ifdef CONFIG_ENV_IS_IN_NAND
+       fail_if_overlap(fcb, env, "FCB", "Environment");
+       fail_if_overlap(fw1, env, "FW1", "Environment");
+#endif
+       fail_if_overlap(fw1, fcb, "FW1", "FCB");
+       if (fw2_set) {
+               fail_if_overlap(fw2, fcb, "FW2", "FCB");
+#ifdef CONFIG_ENV_IS_IN_NAND
+               fail_if_overlap(fw2, env, "FW2", "Environment");
+#endif
+               fail_if_overlap(fw1, fw2, "FW1", "FW2");
+       }
+       fw1_start_block += fw1_skip;
+       fw2_start_block += fw2_skip;
+
+       buf = malloc(erase_size);
+       if (buf == NULL) {
+               printf("Failed to allocate buffer\n");
+               return -ENOMEM;
+       }
+
+       fcb = create_fcb(buf, fw1_start_block,
+                       fw2_start_block, fw_num_blocks);
+       if (IS_ERR(fcb)) {
+               printf("Failed to initialize FCB: %ld\n", PTR_ERR(fcb));
+               free(buf);
+               return PTR_ERR(fcb);
+       }
+
+       ret = write_fcb(buf, fcb_start_block);
+       free(buf);
+       if (ret) {
+               printf("Failed to write FCB to block %lu\n", fcb_start_block);
+               return ret;
+       }
+
+       if (size & (page_size - 1)) {
+               memset(addr + size, 0xff, size & (page_size - 1));
+               size = ALIGN(size, page_size);
+       }
+
+       printf("Programming U-Boot image from %p to block %lu @ %08llx\n",
+               addr, fw1_start_block, (u64)fw1_start_block * mtd->erasesize);
+       ret = tx53_prog_uboot(addr, fw1_start_block, fw1_skip, size,
+                       max_len1);
+       if (ret || fw2_start_block == 0)
+               return ret;
+
+       printf("Programming redundant U-Boot image to block %lu @ %08llx\n",
+               fw2_start_block, (u64)fw2_start_block * mtd->erasesize);
+       ret = tx53_prog_uboot(addr, fw2_start_block, fw2_skip, size,
+                       max_len2);
+       return ret;
+}
+
+U_BOOT_CMD(romupdate, 11, 0, do_update,
+       "Creates an FCB data structure and writes an U-Boot image to flash",
+       "[-f {<part>|block#}] [-r [{<part>|block#}]] [-e #] [<address>] [<length>]\n"
+       "\t-f <part>\twrite bootloader image to partition <part>\n"
+       "\t-f #\t\twrite bootloader image at block # (decimal)\n"
+       "\t-r\t\twrite redundant bootloader image at next free block after first image\n"
+       "\t-r <part>\twrite redundant bootloader image to partition <part>\n"
+       "\t-r #\t\twrite redundant bootloader image at block # (decimal)\n"
+       "\t-e #\t\tspecify number of redundant blocks per boot loader image\n"
+       "\t\t\t(only valid if -f or -r specify a flash address rather than a partition name)\n"
+       "\t-n\t\tshow what would be done without actually updating the flash\n"
+       "\t<address>\tRAM address of bootloader image (default: ${fileaddr})\n"
+       "\t<length>\tlength of bootloader image in RAM (default: ${filesize})"
+       );
diff --git a/board/karo/tx53/lowlevel_init.S b/board/karo/tx53/lowlevel_init.S
new file mode 100644 (file)
index 0000000..32a2ec7
--- /dev/null
@@ -0,0 +1,610 @@
+#include <config.h>
+#include <configs/tx53.h>
+#include <asm/arch/imx-regs.h>
+
+#define DEBUG_LED_BIT          20
+#define LED_GPIO_BASE          GPIO2_BASE_ADDR
+#define LED_MUX_OFFSET         0x174
+#define LED_MUX_MODE           0x11
+
+#define SDRAM_CLK              CONFIG_SYS_SDRAM_CLK
+#define SDRAM_SIZE             (CONFIG_SYS_SDRAM_SIZE / SZ_1M)
+
+#define REG_CCGR0              0x68
+#define REG_CCGR1              0x6c
+#define REG_CCGR2              0x70
+#define REG_CCGR3              0x74
+#define REG_CCGR4              0x78
+#define REG_CCGR5              0x7c
+#define REG_CCGR6              0x80
+#define REG_CCGR7              0x84
+#define REG_CMEOR              0x88
+
+#define CPU_2_BE_32(l)                 \
+       ((((l) << 24) & 0xFF000000) |   \
+       (((l) << 8) & 0x00FF0000) |     \
+       (((l) >> 8) & 0x0000FF00) |     \
+       (((l) >> 24) & 0x000000FF))
+
+/*
+CCM register set                 0x53FD4000 0x53FD7FFF
+EIM register set                 0x63FDA000 0x63FDAFFF
+NANDFC register set              0xF7FF0000 0xF7FFFFFF
+IOMUX Control (IOMUXC) registers 0x53FA8000 0x53FABFFF
+DPLLC1 register                  0x63F80000 0x63F83FFF
+DPLLC2 register                  0x63F84000 0x63F87FFF
+DPLLC3 register                  0x63F88000 0x63F8BFFF
+DPLLC4 register                  0x63F8C000 0x63F8FFFF
+ESD RAM controller register      0x63FD9000 0x63FD9FFF
+M4IF register                    0x63FD8000 0x63FD8FFF
+DDR                              0x70000000 0xEFFFFFFF
+EIM                              0xF0000000 0xF7FEFFFF
+NANDFC Buffers                   0xF7FF0000 0xF7FFFFFF
+IRAM Free Space                  0xF8006000 0xF8017FF0
+GPU Memory                       0xF8020000 0xF805FFFF
+*/
+#define CHECK_DCD_ADDR(a)      (                                       \
+       ((a) >= 0x53fd4000 && (a) <= 0x53fd7fff) /* CCM */ ||           \
+       ((a) >= 0x63fda000 && (a) <= 0x63fdafff) /* EIM (CS0) */ ||     \
+       ((a) >= 0x53fa8000 && (a) <= 0x53fabfff) /* IOMUXC */ ||        \
+       ((a) >= 0x63f80000 && (a) <= 0x63f8ffff) /* DPLLC1..4 */ ||             \
+       ((a) >= 0x63fd8000 && (a) <= 0x63fd9fff) /* M4IF & SDRAM Contr. */ || \
+       ((a) >= 0x70000000 && (a) <= 0xefffffff) /* SDRAM */ ||         \
+       ((a) >= 0xf0000000 && (a) <= 0xf7ffffff) /* EIM & NANDFC buffers */ || \
+       ((a) >= 0xf8006000 && (a) <= 0xf8017ff0) /* IRAM free space */ || \
+       ((a) >= 0xf8020000 && (a) <= 0xf805ffff) /* GPU RAM */)
+
+       .macro  mxc_dcd_item    addr, val
+       .ifne   CHECK_DCD_ADDR(\addr)
+       .word   CPU_2_BE_32(\addr), CPU_2_BE_32(\val)
+       .else
+       .error  "Address \addr not accessible from DCD"
+       .endif
+       .endm
+
+#define MXC_DCD_ITEM(addr, val)                mxc_dcd_item    (addr), (val)
+
+#define MXC_DCD_CMD_SZ_BYTE            1
+#define MXC_DCD_CMD_SZ_SHORT           2
+#define MXC_DCD_CMD_SZ_WORD            4
+#define MXC_DCD_CMD_FLAG_WRITE         0x0
+#define MXC_DCD_CMD_FLAG_CLR           0x1
+#define MXC_DCD_CMD_FLAG_SET           0x3
+#define MXC_DCD_CMD_FLAG_CHK_CLR       ((0 << 0) | (0 << 1))
+#define MXC_DCD_CMD_FLAG_CHK_SET       ((0 << 0) | (1 << 1))
+#define MXC_DCD_CMD_FLAG_CHK_ANY_CLR   ((1 << 0) | (0 << 1))
+#define MXC_DCD_CMD_FLAG_CHK_ANY_SET   ((1 << 0) | (1 << 1))
+
+#define MXC_DCD_START                                                  \
+       .word   CPU_2_BE_32((0xd2 << 24) | ((dcd_end - .) << 8) | DCD_VERSION) ; \
+dcd_start:
+
+       .macro  MXC_DCD_END
+1:
+       .ifgt   . - dcd_start - 1768
+       .error  "DCD too large!"
+       .endif
+dcd_end:
+       .endm
+
+#define MXC_DCD_CMD_WRT(type, flags)                                   \
+1:     .word   CPU_2_BE_32((0xcc << 24) | ((1f - .) << 8) | ((flags) << 3) | (type))
+
+#define MXC_DCD_CMD_CHK(type, flags, addr, mask)                       \
+1:     .word   CPU_2_BE_32((0xcf << 24) | (12 << 8) | ((flags) << 3) | (type)), \
+               CPU_2_BE_32(addr), CPU_2_BE_32(mask)
+
+#define MXC_DCD_CMD_CHK_CNT(type, flags, addr, mask, count)            \
+1:     .word   CPU_2_BE_32((0xcf << 24) | (16 << 8) | ((flags) << 3) | (type)), \
+               CPU_2_BE_32(addr), CPU_2_BE_32(mask), CPU_2_BE_32(count)
+
+#define MXC_DCD_CMD_NOP()                              \
+1:     .word   CPU_2_BE_32((0xc0 << 24) | (4 << 8))
+
+
+#define CK_TO_NS(ck)   (((ck) * 1000 + SDRAM_CLK / 2) / SDRAM_CLK)
+#define NS_TO_CK(ns)   (((ns) * SDRAM_CLK + 999) / 1000)
+#define NS_TO_CK10(ns) DIV_ROUND_UP(NS_TO_CK(ns), 10)
+#define NS_TO_CK100(ns)        DIV_ROUND_UP(NS_TO_CK(ns), 100)
+
+       .macro          CK_VAL, name, clks, offs, max
+       .iflt           \clks - \offs
+       .set            \name, 0
+       .else
+       .ifle           \clks - \offs - \max
+       .set            \name, \clks - \offs
+       .else
+       .error          "Value \clks out of range for parameter \name"
+       .endif
+       .endif
+       .endm
+
+       .macro          NS_VAL, name, ns, offs, max
+       .iflt           \ns - \offs
+       .set            \name, 0
+       .else
+       CK_VAL          \name, NS_TO_CK(\ns), \offs, \max
+       .endif
+       .endm
+
+       .macro          CK_MAX, name, ck1, ck2, offs, max
+       .ifgt           \ck1 - \ck2
+       CK_VAL          \name, \ck1, \offs, \max
+       .else
+       CK_VAL          \name, \ck2, \offs, \max
+       .endif
+       .endm
+
+#define ESDMISC_DDR_TYPE_DDR3          0
+#define ESDMISC_DDR_TYPE_LPDDR2                1
+#define ESDMISC_DDR_TYPE_DDR2          2
+
+#define DIV_ROUND_UP(m,d)              (((m) + (d) - 1) / (d))
+
+#define CKIL_FREQ_Hz                   32768
+#define ESDOR_CLK_PERIOD_ns            (1000000000 / CKIL_FREQ_Hz / 2) /* base clock for ESDOR values */
+
+/* DDR3 SDRAM */
+#define BANK_ADDR_BITS                 CONFIG_NR_DRAM_BANKS
+#define SDRAM_BURST_LENGTH             8
+#define RALAT                          5
+#define WALAT                          0
+#define BI_ON                          0
+#define ADDR_MIRROR                    0
+#define DDR_TYPE                       ESDMISC_DDR_TYPE_DDR3
+
+#if SDRAM_CLK > 666 && SDRAM_CLK <= 800
+#define CL_VAL 11
+#define CWL_VAL        8
+#elif SDRAM_CLK > 533 && SDRAM_CLK <= 666
+#define CL_VAL 9 // or 10
+#define CWL_VAL        7
+#elif SDRAM_CLK > 400 && SDRAM_CLK <= 533
+#define CL_VAL 7 // or 8
+#define CWL_VAL        6
+#elif SDRAM_CLK > 333 && SDRAM_CLK <= 400
+#define CL_VAL 6
+#define CWL_VAL        5
+#elif SDRAM_CLK >= 303 && SDRAM_CLK <= 333
+#define CL_VAL 5
+#define CWL_VAL        5
+#else
+#error SDRAM clock out of range: 303 .. 800
+#endif
+
+#if SDRAM_SIZE < 2048
+/* 512/1024MiB SDRAM: NT5CB128M16FP-DII */
+
+#define ROW_ADDR_BITS                  14
+#define COL_ADDR_BITS                  10
+
+/* ESDCFG0 0x0c */
+NS_VAL tRFC,   160, 1, 255             /* clks - 1 (0..255) */
+CK_MAX tXS,    NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) tRFC + 10 */
+CK_MAX tXP,    NS_TO_CK10(75), 3, 1, 7 /* clks - 1 (0..7) */ /* max(3tCK, 7.5ns) */
+CK_MAX tXPDLL, NS_TO_CK(24), 2, 1, 15  /* clks - 1 (0..15) */
+NS_VAL tFAW,   50, 1, 31               /* clks - 1 (0..31) */
+CK_VAL tCL,    CL_VAL, 3, 8            /* clks - 3 (0..8) CAS Latency */
+
+/* ESDCFG1 0x10 */
+CK_VAL tRCD,   NS_TO_CK10(125), 1, 7   /* clks - 1 (0..7) */ /* 12.5 */
+CK_VAL tRP,    NS_TO_CK10(125), 1, 7   /* clks - 1 (0..7) */ /* 12.5 */
+NS_VAL tRC,    50, 1, 31               /* clks - 1 (0..31) */
+CK_VAL tRAS,   NS_TO_CK10(375), 1, 31  /* clks - 1 (0..31) */ /* 37.5 */
+CK_VAL tRPA,   1, 0, 1                 /* clks     (0..1) */
+NS_VAL tWR,    15, 1, 15               /* clks - 1 (0..15) */
+CK_VAL tMRD,   4, 1, 15                /* clks - 1 (0..15) */
+CK_VAL tCWL,   CWL_VAL, 2, 6           /* clks - 2 (0..6) */
+
+/* ESDCFG2 0x14 */
+CK_VAL tDLLK,  512, 1, 511             /* clks - 1 (0..511) */
+CK_MAX tRTP,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+CK_MAX tWTR,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+CK_MAX tRRD,   NS_TO_CK(10), 4, 1, 7   /* clks - 1 (0..7) */
+
+/* ESDOR 0x30 */
+CK_MAX tXPR,   NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) max(tRFC + 10, 5CK) */
+#else
+/* 4096MiB SDRAM: IM4G16D3EABG-125I */
+
+#define ROW_ADDR_BITS                  15
+#define COL_ADDR_BITS                  10
+
+/* ESDCFG0 0x0c */
+NS_VAL tRFC,   260, 1, 255             /* clks - 1 (0..255) */
+CK_MAX tXS,    NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) tRFC + 10 */
+CK_MAX tXP,    NS_TO_CK(6), 3, 1, 7 /* clks - 1 (0..7) */ /* max(3tCK, 7.5ns) */
+CK_MAX tXPDLL, NS_TO_CK(24), 2, 1, 15  /* clks - 1 (0..15) */
+NS_VAL tFAW,   30, 1, 31               /* clks - 1 (0..31) */
+CK_VAL tCL,    CL_VAL, 3, 8            /* clks - 3 (0..8) CAS Latency */
+
+/* ESDCFG1 0x10 */
+CK_VAL tRCD,   NS_TO_CK100(1375), 1, 7 /* clks - 1 (0..7) */ /* 13.75 */
+CK_VAL tRP,    NS_TO_CK100(1375), 1, 7 /* clks - 1 (0..7) */ /* 13.75 */
+CK_VAL tRC,    NS_TO_CK100(4875), 1, 31 /* clks - 1 (0..31) */ /* 48.75 */
+CK_VAL tRAS,   NS_TO_CK(35), 1, 31     /* clks - 1 (0..31) */ /* 35 */
+CK_VAL tRPA,   1, 0, 1                 /* clks     (0..1) */
+NS_VAL tWR,    15, 1, 15               /* clks - 1 (0..15) */
+CK_VAL tMRD,   4, 1, 15                /* clks - 1 (0..15) */
+CK_VAL tCWL,   CWL_VAL, 2, 6           /* clks - 2 (0..6) */
+
+/* ESDCFG2 0x14 */
+CK_VAL tDLLK,  512, 1, 511             /* clks - 1 (0..511) */
+CK_MAX tRTP,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+CK_MAX tWTR,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+CK_MAX tRRD,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+
+/* ESDOR 0x30 */
+CK_MAX tXPR,   NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) max(tRFC + 10, 5CK) */
+#endif
+
+#define tSDE_RST                       (DIV_ROUND_UP(200000, ESDOR_CLK_PERIOD_ns) + 1)
+                                       /* Add an extra (or two?) ESDOR_CLK_PERIOD_ns according to
+                                        * erroneous Erratum Engcm12377
+                                        */
+#define tRST_CKE                       (DIV_ROUND_UP(500000 + 2 * ESDOR_CLK_PERIOD_ns, ESDOR_CLK_PERIOD_ns) + 1)
+
+/* ESDOTC 0x08 */
+CK_VAL tAOFPD, NS_TO_CK10(85), 1, 7    /* clks - 1 (0..7) */ /* 8.5ns */
+CK_VAL tAONPD, NS_TO_CK10(85), 1, 7    /* clks - 1 (0..7) */ /* 8.5ns */
+CK_VAL tANPD,  tCWL + 1, 1, 15         /* clks - 1 (0..15) */
+CK_VAL tAXPD,  tCWL + 1, 1, 15         /* clks - 1 (0..15) */
+CK_VAL tODTLon tCWL, 0, 7              /* clks - 1 (0..7) */ /* CWL+AL-2 */
+CK_VAL tODTLoff tCWL, 0, 31            /* clks - 1 (0..31) */ /* CWL+AL-2 */
+
+/* ESDPDC 0x04 */
+CK_MAX tCKE,   NS_TO_CK(5), 3, 1, 7
+CK_MAX tCKSRX, NS_TO_CK(10), 5, 0, 7
+CK_MAX tCKSRE, NS_TO_CK(10), 5, 0, 7
+
+#define PRCT           0
+#define PWDT           5
+#define SLOW_PD                0
+#define BOTH_CS_PD     1
+
+#define ESDPDC_VAL_0   (       \
+       (PRCT << 28) |          \
+       (PRCT << 24) |          \
+       (tCKE << 16) |          \
+       (SLOW_PD << 7) |        \
+       (BOTH_CS_PD << 6) |     \
+       (tCKSRX << 3) |         \
+       (tCKSRE << 0)           \
+       )
+
+#define ESDPDC_VAL_1   (ESDPDC_VAL_0 |         \
+       (PWDT << 12) |                          \
+       (PWDT << 8)                             \
+       )
+
+#define Rtt_Nom                                1 /* ODT: 0: off 1: RZQ/4 2: RZQ/2 3: RZQ/6 4: RZQ/12 5: RZQ/8 */
+#define Rtt_WR                         0 /* Dynamic ODT: 0: off 1: RZQ/4 2: RZQ/2 */
+#define DLL_DISABLE                    0
+
+       .iflt   tWR - 7
+       .set    mr0_val, (((1 - DLL_DISABLE) << 8) /* DLL Reset */ |    \
+                       (SLOW_PD << 12) /* PD exit: 0: fast 1: slow */ |\
+                       ((tWR + 1 - 4) << 9) |                          \
+                       ((((tCL + 3) - 4) & 0x7) << 4) |                \
+                       ((((tCL + 3) - 4) & 0x8) >> 1))
+       .else
+       .set    mr0_val, ((1 << 8) /* DLL Reset */ |                    \
+                       (SLOW_PD << 12) /* PD exit: 0: fast 1: slow */ |\
+                       (((tWR + 1) / 2) << 9) |        \
+                       ((((tCL + 3) - 4) & 0x7) << 4) | \
+                       ((((tCL + 3) - 4) & 0x8) >> 1))
+       .endif
+
+#define mr1_val                                (                                       \
+                                        ((Rtt_Nom & 1) << 2) |                 \
+                                        (((Rtt_Nom >> 1) & 1) << 6) |          \
+                                        (((Rtt_Nom >> 2) & 1) << 9) |          \
+                                        (DLL_DISABLE << 0) |                   \
+                                       0)
+#define mr2_val                                (                                       \
+                                        (Rtt_WR << 9) /* dynamic ODT */ |      \
+                                        (0 << 7) /* SRT: Ext. temp. (mutually exclusive with ASR!) */ | \
+                                        (1 << 6) | /* ASR: Automatic Self Refresh */ \
+                                        (((tCWL + 2) - 5) << 3) |              \
+                                       0)
+#define mr3_val                                0
+
+#define ESDSCR_MRS_VAL(cs, mr, val)    (((val) << 16) |                \
+                                       (1 << 15) /* CON_REQ */ |       \
+                                       0x80 |                          \
+                                       (3 << 4) /* MRS command */ |    \
+                                       ((cs) << 3) |                   \
+                                       ((mr) << 0) |                   \
+                                       0)
+
+#define ESDCFG0_VAL    (       \
+       (tRFC << 24) |          \
+       (tXS << 16) |           \
+       (tXP << 13) |           \
+       (tXPDLL << 9) |         \
+       (tFAW << 4) |           \
+       (tCL << 0))             \
+
+#define ESDCFG1_VAL    (       \
+       (tRCD << 29) |          \
+       (tRP << 26) |           \
+       (tRC << 21) |           \
+       (tRAS << 16) |          \
+       (tRPA << 15) |          \
+       (tWR << 9) |            \
+       (tMRD << 5) |           \
+       (tCWL << 0))            \
+
+#define ESDCFG2_VAL    (       \
+       (tDLLK << 16) |         \
+       (tRTP << 6) |           \
+       (tWTR << 3) |           \
+       (tRRD << 0))
+
+#define BURST_LEN              (SDRAM_BURST_LENGTH / 8) /* 0: 4 byte 1: 8 byte */
+
+#define ESDCTL_VAL             (((ROW_ADDR_BITS - 11) << 24) |         \
+                               ((COL_ADDR_BITS - 9) << 20) |           \
+                               (BURST_LEN << 19) |                     \
+                               (1 << 16) | /* SDRAM bus width */       \
+                               ((-1) << (32 - BANK_ADDR_BITS)))
+
+#define ESDMISC_VAL            ((ADDR_MIRROR << 19) |  \
+                               (WALAT << 16) |         \
+                               (BI_ON << 12) |         \
+                               (0x3 << 9) |            \
+                               (RALAT << 6) |          \
+                               (DDR_TYPE << 3))
+
+#define ESDOR_VAL              ((tXPR << 16) | (tSDE_RST << 8) | (tRST_CKE << 0))
+
+#define ESDOTC_VAL             ((tAOFPD << 27) |       \
+                               (tAONPD << 24) |        \
+                               (tANPD << 20) |         \
+                               (tAXPD << 16) |         \
+                               (tODTLon << 12) |       \
+                               (tODTLoff << 4))
+
+fcb_start:
+       b       _start
+       .word   0x20424346      /* "FCB " marker */
+       .word   0x01    /* FCB version number */
+       .org    0x68
+       .word   0x0     /* primary image starting page number */
+       .word   0x0     /* secondary image starting page number */
+       .org    0x78
+       .word   0x0     /* DBBT start page (0 == NO DBBT) */
+       .word   0       /* Bad block marker offset in main area (unused) */
+       .org    0xac
+       .word   0       /* BI Swap disabled */
+       .word   0       /* Bad Block marker offset in spare area */
+fcb_end:
+
+       .org    0x400
+ivt_header:
+       .word   CPU_2_BE_32((0xd1 << 24) | (32 << 8) | 0x40)
+app_start_addr:
+       .long   _start
+       .long   0x0
+dcd_ptr:
+       .long   dcd_hdr
+boot_data_ptr:
+       .word   boot_data
+self_ptr:
+       .word   ivt_header
+app_code_csf:
+       .word   0x0
+       .word   0x0
+boot_data:
+       .long   fcb_start
+image_len:
+       .long   __uboot_img_end - fcb_start
+plugin:
+       .word   0
+ivt_end:
+#define DCD_VERSION    0x40
+
+dcd_hdr:
+       MXC_DCD_START
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
+       MXC_DCD_ITEM(0x53fa8004, 0x00194005)    @ set LDO to 1.3V
+
+       /* disable all irrelevant clocks */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR0, 0xffcf0fff)
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR1, 0x000fffcf)
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR2, 0x033c0000)
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR3, 0x000000ff)
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR4, 0x00000000)
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR5, 0x00fff033)
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR6, 0x0f00030f)
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CCGR7, 0xfff00000)
+       MXC_DCD_ITEM(CCM_BASE_ADDR + REG_CMEOR, 0x00000000)
+
+       MXC_DCD_ITEM(IOMUXC_BASE_ADDR + 0x340, 0x11)    /* GPIO_17 => RESET_OUT */
+
+       MXC_DCD_ITEM(0x63fd800c, 0x00000000)    /* M4IF: MUX NFC signals on WEIM */
+#if SDRAM_CLK > 333
+       MXC_DCD_ITEM(0x53fd4014, 0x00888944)    /* CBCDR */
+#else
+       MXC_DCD_ITEM(0x53fd4014, 0x00888644)    /* CBCDR */
+#endif
+       MXC_DCD_ITEM(0x53fd4018, 0x00016154)    /* CBCMR */
+
+       MXC_DCD_ITEM(0x53fd401c, 0xa6a2a020)    /* CSCMR1 */
+       MXC_DCD_ITEM(0x53fd4020, 0xb6b12f0a)    /* CSCMR2 */
+       MXC_DCD_ITEM(0x53fd4024, 0x00080b18)    /* CSCDR1 */
+
+#define DDR_SEL_VAL    0
+#define DSE_VAL                6
+#define ODT_VAL                2
+
+#define DDR_SEL_SHIFT  25
+#define ODT_SHIFT      22
+#define DSE_SHIFT      19
+#define DDR_INPUT_SHIFT        9
+#define HYS_SHIFT      8
+#define PKE_SHIFT      7
+#define PUE_SHIFT      6
+#define PUS_SHIFT      4
+
+#define DDR_SEL_MASK   (DDR_SEL_VAL << DDR_SEL_SHIFT)
+#define DSE_MASK       (DSE_VAL << DSE_SHIFT)
+#define ODT_MASK       (ODT_VAL << ODT_SHIFT)
+
+#define DQM_VAL                DSE_MASK
+#define SDQS_VAL       (ODT_MASK | DSE_MASK | (1 << PUE_SHIFT))
+#define SDODT_VAL      (DSE_MASK | (0 << PKE_SHIFT) | (1 << PUE_SHIFT) | (0 << PUS_SHIFT))
+#define SDCLK_VAL      DSE_MASK
+#define SDCKE_VAL      ((1 << PKE_SHIFT) | (1 << PUE_SHIFT) | (0 << PUS_SHIFT))
+
+       MXC_DCD_ITEM(0x53fa8724, DDR_SEL_MASK) /* DDR_TYPE: DDR3 */
+       MXC_DCD_ITEM(0x53fa86f4, 0 << DDR_INPUT_SHIFT) /* DDRMODE_CTL */
+       MXC_DCD_ITEM(0x53fa8714, 0 << DDR_INPUT_SHIFT) /* GRP_DDRMODE */
+       MXC_DCD_ITEM(0x53fa86fc, 1 << PKE_SHIFT) /* GRP_DDRPKE */
+       MXC_DCD_ITEM(0x53fa8710, 0 << HYS_SHIFT) /* GRP_DDRHYS */
+       MXC_DCD_ITEM(0x53fa8708, 1 << PUE_SHIFT) /* GRP_DDRPK */
+
+       MXC_DCD_ITEM(0x53fa8584, DQM_VAL) /* DQM0 */
+       MXC_DCD_ITEM(0x53fa8594, DQM_VAL) /* DQM1 */
+       MXC_DCD_ITEM(0x53fa8560, DQM_VAL) /* DQM2 */
+       MXC_DCD_ITEM(0x53fa8554, DQM_VAL) /* DQM3 */
+
+       MXC_DCD_ITEM(0x53fa857c, SDQS_VAL) /* SDQS0 */
+       MXC_DCD_ITEM(0x53fa8590, SDQS_VAL) /* SDQS1 */
+       MXC_DCD_ITEM(0x53fa8568, SDQS_VAL) /* SDQS2 */
+       MXC_DCD_ITEM(0x53fa8558, SDQS_VAL) /* SDQS3 */
+
+       MXC_DCD_ITEM(0x53fa8580, SDODT_VAL) /* SDODT0 */
+       MXC_DCD_ITEM(0x53fa8578, SDCLK_VAL) /* SDCLK0 */
+
+       MXC_DCD_ITEM(0x53fa8564, SDODT_VAL) /* SDODT1 */
+       MXC_DCD_ITEM(0x53fa8570, SDCLK_VAL) /* SDCLK1 */
+
+       MXC_DCD_ITEM(0x53fa858c, SDCKE_VAL) /* SDCKE0 */
+       MXC_DCD_ITEM(0x53fa855c, SDCKE_VAL) /* SDCKE1 */
+
+       MXC_DCD_ITEM(0x53fa8574, DSE_MASK) /* DRAM_CAS */
+       MXC_DCD_ITEM(0x53fa8588, DSE_MASK) /* DRAM_RAS */
+
+       MXC_DCD_ITEM(0x53fa86f0, DSE_MASK) /* GRP_ADDDS */
+       MXC_DCD_ITEM(0x53fa8720, DSE_MASK) /* GRP_CTLDS */
+       MXC_DCD_ITEM(0x53fa8718, DSE_MASK) /* GRP_B0DS */
+       MXC_DCD_ITEM(0x53fa871c, DSE_MASK) /* GRP_B1DS */
+       MXC_DCD_ITEM(0x53fa8728, DSE_MASK) /* GRP_B2DS */
+       MXC_DCD_ITEM(0x53fa872c, DSE_MASK) /* GRP_B3DS */
+
+       /* calibration defaults */
+       MXC_DCD_ITEM(0x63fd904c, 0x001f001f)
+       MXC_DCD_ITEM(0x63fd9050, 0x001f001f)
+       MXC_DCD_ITEM(0x63fd907c, 0x011e011e)
+       MXC_DCD_ITEM(0x63fd9080, 0x011f0120)
+       MXC_DCD_ITEM(0x63fd9088, 0x3a393d3b)
+       MXC_DCD_ITEM(0x63fd9090, 0x3f3f3f3f)
+
+       MXC_DCD_ITEM(0x63fd9018, ESDMISC_VAL)
+       MXC_DCD_ITEM(0x63fd9000, ESDCTL_VAL)
+       MXC_DCD_ITEM(0x63fd900c, ESDCFG0_VAL)
+       MXC_DCD_ITEM(0x63fd9010, ESDCFG1_VAL)
+       MXC_DCD_ITEM(0x63fd9014, ESDCFG2_VAL)
+
+       MXC_DCD_ITEM(0x63fd902c, 0x000026d2)
+       MXC_DCD_ITEM(0x63fd9030, ESDOR_VAL)
+       MXC_DCD_ITEM(0x63fd9008, ESDOTC_VAL)
+       MXC_DCD_ITEM(0x63fd9004, ESDPDC_VAL_0)
+
+       /* MR0..3 - CS0 */
+       MXC_DCD_ITEM(0x63fd901c, 0x00008000) /* CON_REQ */
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_SET, 0x63fd901c, 0x00004000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 2, mr2_val)) /* MRS: MR2 */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, mr3_val)) /* MRS: MR3 */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 1, mr1_val)) /* MRS: MR1 */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 0, mr0_val)) /* MRS: MR0 */
+#if BANK_ADDR_BITS > 1
+       /* MR0..3 - CS1 */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1, 2, 0x0000)) /* MRS: MR2 */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1, 3, 0x0000)) /* MRS: MR3 */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1, 1, 0x0040)) /* MRS: MR1 */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(1, 0, mr0_val)) /* MRS: MR0 */
+#endif
+       MXC_DCD_ITEM(0x63fd9020, 3 << 14) /* disable refresh during calibration */
+       MXC_DCD_ITEM(0x63fd9058, 0x00022222)
+
+       MXC_DCD_ITEM(0x63fd90d0, 0x00000003) /* select default compare pattern for calibration */
+
+       /* ZQ calibration */
+       MXC_DCD_ITEM(0x63fd901c, 0x04008010) /* precharge all */
+       MXC_DCD_ITEM(0x63fd901c, 0x00008040) /* MRS: ZQ calibration */
+       MXC_DCD_ITEM(0x63fd9040, 0x0539002b) /* Force ZQ calibration */
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, 0x63fd9040, 0x00010000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
+       /* DQS calibration */
+       MXC_DCD_ITEM(0x63fd901c, 0x04008010) /* precharge all */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, (1 << 2))) /* MRS: select MPR */
+       MXC_DCD_ITEM(0x63fd907c, 0x90000000) /* reset RD fifo and start DQS calib. */
+
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, 0x63fd907c, 0x90000000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
+
+       /* WR DL calibration */
+       MXC_DCD_ITEM(0x63fd901c, 0x00008000)
+       MXC_DCD_ITEM(0x63fd901c, 0x04008010) /* precharge all */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, (1 << 2))) /* MRS: select MPR */
+       MXC_DCD_ITEM(0x63fd90a4, 0x00000010)
+
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, 0x63fd90a4, 0x00000010)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
+
+       /* RD DL calibration */
+       MXC_DCD_ITEM(0x63fd901c, 0x04008010) /* precharge all */
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, (1 << 2))) /* MRS: select MPR */
+       MXC_DCD_ITEM(0x63fd90a0, 0x00000010)
+
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, 0x63fd90a0, 0x00000010)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+       MXC_DCD_ITEM(0x63fd901c, ESDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
+       MXC_DCD_ITEM(0x63fd9020, (3 << 11) | (0 << 14)) /* refresh interval: 4 cycles every 64kHz period */
+       MXC_DCD_ITEM(0x63fd9004, ESDPDC_VAL_1)
+
+       /* DDR calibration done */
+       MXC_DCD_ITEM(0x63fd901c, 0x00000000)
+
+       /* setup NFC pads */
+       /* MUX_SEL */
+       MXC_DCD_ITEM(0x53fa819c, 0x00000000)    @ EIM_DA0
+       MXC_DCD_ITEM(0x53fa81a0, 0x00000000)    @ EIM_DA1
+       MXC_DCD_ITEM(0x53fa81a4, 0x00000000)    @ EIM_DA2
+       MXC_DCD_ITEM(0x53fa81a8, 0x00000000)    @ EIM_DA3
+       MXC_DCD_ITEM(0x53fa81ac, 0x00000000)    @ EIM_DA4
+       MXC_DCD_ITEM(0x53fa81b0, 0x00000000)    @ EIM_DA5
+       MXC_DCD_ITEM(0x53fa81b4, 0x00000000)    @ EIM_DA6
+       MXC_DCD_ITEM(0x53fa81b8, 0x00000000)    @ EIM_DA7
+       MXC_DCD_ITEM(0x53fa81dc, 0x00000000)    @ WE_B
+       MXC_DCD_ITEM(0x53fa81e0, 0x00000000)    @ RE_B
+       MXC_DCD_ITEM(0x53fa8228, 0x00000000)    @ CLE
+       MXC_DCD_ITEM(0x53fa822c, 0x00000000)    @ ALE
+       MXC_DCD_ITEM(0x53fa8230, 0x00000000)    @ WP_B
+       MXC_DCD_ITEM(0x53fa8234, 0x00000000)    @ RB0
+       MXC_DCD_ITEM(0x53fa8238, 0x00000000)    @ CS0
+       /* PAD_CTL */
+       MXC_DCD_ITEM(0x53fa84ec, 0x000000e4)    @ EIM_DA0
+       MXC_DCD_ITEM(0x53fa84f0, 0x000000e4)    @ EIM_DA1
+       MXC_DCD_ITEM(0x53fa84f4, 0x000000e4)    @ EIM_DA2
+       MXC_DCD_ITEM(0x53fa84f8, 0x000000e4)    @ EIM_DA3
+       MXC_DCD_ITEM(0x53fa84fc, 0x000000e4)    @ EIM_DA4
+       MXC_DCD_ITEM(0x53fa8500, 0x000000e4)    @ EIM_DA5
+       MXC_DCD_ITEM(0x53fa8504, 0x000000e4)    @ EIM_DA6
+       MXC_DCD_ITEM(0x53fa8508, 0x000000e4)    @ EIM_DA7
+       MXC_DCD_ITEM(0x53fa852c, 0x00000004)    @ NANDF_WE_B
+       MXC_DCD_ITEM(0x53fa8530, 0x00000004)    @ NANDF_RE_B
+       MXC_DCD_ITEM(0x53fa85a0, 0x00000004)    @ NANDF_CLE_B
+       MXC_DCD_ITEM(0x53fa85a4, 0x00000004)    @ NANDF_ALE_B
+       MXC_DCD_ITEM(0x53fa85a8, 0x000000e4)    @ NANDF_WE_B
+       MXC_DCD_ITEM(0x53fa85ac, 0x000000e4)    @ NANDF_RB0
+       MXC_DCD_ITEM(0x53fa85b0, 0x00000004)    @ NANDF_CS0
+       MXC_DCD_END
diff --git a/board/karo/tx53/tx53.c b/board/karo/tx53/tx53.c
new file mode 100644 (file)
index 0000000..26caf9d
--- /dev/null
@@ -0,0 +1,1452 @@
+/*
+ * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
+ * based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <i2c.h>
+#include <lcd.h>
+#include <netdev.h>
+#include <mmc.h>
+#include <fsl_esdhc.h>
+#include <video_fb.h>
+#include <ipu.h>
+#include <mxcfb.h>
+#include <linux/fb.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/iomux-mx53.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/sys_proto.h>
+
+#include "../common/karo.h"
+
+#define TX53_FEC_RST_GPIO      IMX_GPIO_NR(7, 6)
+#define TX53_FEC_PWR_GPIO      IMX_GPIO_NR(3, 20)
+#define TX53_FEC_INT_GPIO      IMX_GPIO_NR(2, 4)
+#define TX53_LED_GPIO          IMX_GPIO_NR(2, 20)
+
+#define TX53_LCD_PWR_GPIO      IMX_GPIO_NR(2, 31)
+#define TX53_LCD_RST_GPIO      IMX_GPIO_NR(3, 29)
+#define TX53_LCD_BACKLIGHT_GPIO        IMX_GPIO_NR(1, 1)
+
+#define TX53_RESET_OUT_GPIO    IMX_GPIO_NR(7, 12)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MX53_GPIO_PAD_CTRL     MUX_PAD_CTRL(PAD_CTL_PKE | PAD_CTL_PUE | \
+                               PAD_CTL_DSE_HIGH | PAD_CTL_PUS_22K_UP)
+
+#define TX53_SDHC_PAD_CTRL     MUX_PAD_CTRL(PAD_CTL_HYS | PAD_CTL_DSE_HIGH |   \
+                               PAD_CTL_SRE_FAST | PAD_CTL_PUS_47K_UP)
+
+char __uboot_img_end[0] __attribute__((section(".__uboot_img_end")));
+
+static iomux_v3_cfg_t tx53_pads[] = {
+       /* NAND flash pads are set up in lowlevel_init.S */
+
+       /* UART pads */
+#if CONFIG_MXC_UART_BASE == UART1_BASE
+       MX53_PAD_PATA_DIOW__UART1_TXD_MUX,
+       MX53_PAD_PATA_DMACK__UART1_RXD_MUX,
+       MX53_PAD_PATA_IORDY__UART1_RTS,
+       MX53_PAD_PATA_RESET_B__UART1_CTS,
+#endif
+#if CONFIG_MXC_UART_BASE == UART2_BASE
+       MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX,
+       MX53_PAD_PATA_DMARQ__UART2_TXD_MUX,
+       MX53_PAD_PATA_DIOR__UART2_RTS,
+       MX53_PAD_PATA_INTRQ__UART2_CTS,
+#endif
+#if CONFIG_MXC_UART_BASE == UART3_BASE
+       MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
+       MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
+       MX53_PAD_PATA_DA_2__UART3_RTS,
+       MX53_PAD_PATA_DA_1__UART3_CTS,
+#endif
+       /* internal I2C */
+       MX53_PAD_EIM_D28__I2C1_SDA | MX53_GPIO_PAD_CTRL,
+       MX53_PAD_EIM_D21__I2C1_SCL | MX53_GPIO_PAD_CTRL,
+
+       /* FEC PHY GPIO functions */
+       MX53_PAD_EIM_D20__GPIO3_20, /* PHY POWER */
+       MX53_PAD_PATA_DA_0__GPIO7_6, /* PHY RESET */
+       MX53_PAD_PATA_DATA4__GPIO2_4, /* PHY INT */
+
+       /* FEC functions */
+       MX53_PAD_FEC_MDC__FEC_MDC,
+       MX53_PAD_FEC_MDIO__FEC_MDIO,
+       MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
+       MX53_PAD_FEC_RX_ER__FEC_RX_ER,
+       MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
+       MX53_PAD_FEC_RXD1__FEC_RDATA_1,
+       MX53_PAD_FEC_RXD0__FEC_RDATA_0,
+       MX53_PAD_FEC_TX_EN__FEC_TX_EN,
+       MX53_PAD_FEC_TXD1__FEC_TDATA_1,
+       MX53_PAD_FEC_TXD0__FEC_TDATA_0,
+};
+
+static const struct gpio tx53_gpios[] = {
+       { TX53_RESET_OUT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "#RESET_OUT", },
+       { TX53_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY PWR", },
+       { TX53_FEC_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY RESET", },
+       { TX53_FEC_INT_GPIO, GPIOFLAG_INPUT, "FEC PHY INT", },
+};
+
+/*
+ * Functions
+ */
+/* placed in section '.data' to prevent overwriting relocation info
+ * overlayed with bss
+ */
+static u32 wrsr __attribute__((section(".data")));
+
+#define WRSR_POR       (1 << 4)
+#define WRSR_TOUT      (1 << 1)
+#define WRSR_SFTW      (1 << 0)
+
+static void print_reset_cause(void)
+{
+       struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+       void __iomem *wdt_base = (void __iomem *)WDOG1_BASE_ADDR;
+       u32 srsr;
+       char *dlm = "";
+
+       printf("Reset cause: ");
+
+       srsr = readl(&src_regs->srsr);
+       wrsr = readw(wdt_base + 4);
+
+       if (wrsr & WRSR_POR) {
+               printf("%sPOR", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00004) {
+               printf("%sCSU", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00008) {
+               printf("%sIPP USER", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00010) {
+               if (wrsr & WRSR_SFTW) {
+                       printf("%sSOFT", dlm);
+                       dlm = " | ";
+               }
+               if (wrsr & WRSR_TOUT) {
+                       printf("%sWDOG", dlm);
+                       dlm = " | ";
+               }
+       }
+       if (srsr & 0x00020) {
+               printf("%sJTAG HIGH-Z", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00040) {
+               printf("%sJTAG SW", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x10000) {
+               printf("%sWARM BOOT", dlm);
+               dlm = " | ";
+       }
+       if (dlm[0] == '\0')
+               printf("unknown");
+
+       printf("\n");
+}
+
+#define pr_lpgr_val(v, n, b, c) do {                                   \
+       u32 __v = ((v) >> (b)) & ((1 << (c)) - 1);                      \
+       if (__v)                                                        \
+               printf(" %s=%0*x", #n, DIV_ROUND_UP(c, 4), __v);        \
+} while (0)
+
+static inline void print_lpgr(u32 lpgr)
+{
+       if (!lpgr)
+               return;
+
+       printf("LPGR=%08x:", lpgr);
+       pr_lpgr_val(lpgr, SW_ISO, 31, 1);
+       pr_lpgr_val(lpgr, SECONDARY_BOOT, 30, 1);
+       pr_lpgr_val(lpgr, BLOCK_REWRITE, 29, 1);
+       pr_lpgr_val(lpgr, WDOG_BOOT, 28, 1);
+       pr_lpgr_val(lpgr, SBMR_SHADOW, 0, 26);
+       printf("\n");
+}
+
+static void tx53_print_cpuinfo(void)
+{
+       u32 cpurev;
+       struct srtc_regs *srtc_regs = (void *)SRTC_BASE_ADDR;
+       u32 lpgr = readl(&srtc_regs->lpgr);
+
+       cpurev = get_cpu_rev();
+
+       printf("CPU:   Freescale i.MX53 rev%d.%d at %d MHz\n",
+               (cpurev & 0x000F0) >> 4,
+               (cpurev & 0x0000F) >> 0,
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+
+       print_reset_cause();
+
+       print_lpgr(lpgr);
+
+       if (lpgr & (1 << 30))
+               printf("WARNING: U-Boot started from secondary bootstrap image\n");
+
+       if (lpgr) {
+               struct mxc_ccm_reg *ccm_regs = (void *)CCM_BASE_ADDR;
+               u32 ccgr4 = readl(&ccm_regs->CCGR4);
+
+               writel(ccgr4 | MXC_CCM_CCGR4_SRTC(3), &ccm_regs->CCGR4);
+               writel(0, &srtc_regs->lpgr);
+               writel(ccgr4, &ccm_regs->CCGR4);
+       }
+}
+
+enum LTC3589_REGS {
+       LTC3589_SCR1 = 0x07,
+       LTC3589_SCR2 = 0x12,
+       LTC3589_VCCR = 0x20,
+       LTC3589_CLIRQ = 0x21,
+       LTC3589_B1DTV1 = 0x23,
+       LTC3589_B1DTV2 = 0x24,
+       LTC3589_VRRCR = 0x25,
+       LTC3589_B2DTV1 = 0x26,
+       LTC3589_B2DTV2 = 0x27,
+       LTC3589_B3DTV1 = 0x29,
+       LTC3589_B3DTV2 = 0x2a,
+       LTC3589_L2DTV1 = 0x32,
+       LTC3589_L2DTV2 = 0x33,
+};
+
+#define LTC3589_BnDTV1_PGOOD_MASK      (1 << 5)
+#define LTC3589_BnDTV1_SLEW(n)         (((n) & 3) << 6)
+
+#define LTC3589_CLK_RATE_LOW           (1 << 5)
+
+#define LTC3589_SCR2_PGOOD_SHUTDWN     (1 << 7)
+
+#define VDD_LDO2_VAL           mV_to_regval(vout_to_vref(1325 * 10, 2))
+#define VDD_CORE_VAL           mV_to_regval(vout_to_vref(1100 * 10, 3))
+#define VDD_SOC_VAL            mV_to_regval(vout_to_vref(1325 * 10, 4))
+#define VDD_BUCK3_VAL          mV_to_regval(vout_to_vref(2500 * 10, 5))
+
+#ifndef CONFIG_SYS_TX53_HWREV_2
+/* LDO2 vref divider */
+#define R1_2   180
+#define R2_2   191
+/* BUCK1 vref divider */
+#define R1_3   150
+#define R2_3   180
+/* BUCK2 vref divider */
+#define R1_4   180
+#define R2_4   191
+/* BUCK3 vref divider */
+#define R1_5   270
+#define R2_5   100
+#else
+/* no dividers on vref */
+#define R1_2   0
+#define R2_2   1
+#define R1_3   0
+#define R2_3   1
+#define R1_4   0
+#define R2_4   1
+#define R1_5   0
+#define R2_5   1
+#endif
+
+/* calculate voltages in 10mV */
+#define R1(idx)                        R1_##idx
+#define R2(idx)                        R2_##idx
+
+#define vout_to_vref(vout, idx)        ((vout) * R2(idx) / (R1(idx) + R2(idx)))
+#define vref_to_vout(vref, idx)        DIV_ROUND_UP((vref) * (R1(idx) + R2(idx)), R2(idx))
+
+#define mV_to_regval(mV)       DIV_ROUND(((((mV) < 3625) ? 3625 : (mV)) - 3625), 125)
+#define regval_to_mV(v)                (((v) * 125 + 3625))
+
+static struct pmic_regs {
+       enum LTC3589_REGS addr;
+       u8 val;
+} ltc3589_regs[] = {
+       { LTC3589_SCR1, 0x15, }, /* burst mode for all regulators except buck boost */
+       { LTC3589_SCR2, LTC3589_SCR2_PGOOD_SHUTDWN, }, /* enable shutdown on PGOOD Timeout */
+
+       { LTC3589_L2DTV1, VDD_LDO2_VAL | LTC3589_BnDTV1_SLEW(3) | LTC3589_BnDTV1_PGOOD_MASK, },
+       { LTC3589_L2DTV2, VDD_LDO2_VAL | LTC3589_CLK_RATE_LOW, },
+
+       { LTC3589_B1DTV1, VDD_CORE_VAL | LTC3589_BnDTV1_SLEW(3) | LTC3589_BnDTV1_PGOOD_MASK, },
+       { LTC3589_B1DTV2, VDD_CORE_VAL, },
+
+       { LTC3589_B2DTV1, VDD_SOC_VAL | LTC3589_BnDTV1_SLEW(3) | LTC3589_BnDTV1_PGOOD_MASK, },
+       { LTC3589_B2DTV2, VDD_SOC_VAL, },
+
+       { LTC3589_B3DTV1, VDD_BUCK3_VAL | LTC3589_BnDTV1_SLEW(3) | LTC3589_BnDTV1_PGOOD_MASK, },
+       { LTC3589_B3DTV2, VDD_BUCK3_VAL, },
+
+       /* Select ref 0 for all regulators and enable slew */
+       { LTC3589_VCCR, 0x55, },
+
+       { LTC3589_CLIRQ, 0, }, /* clear all interrupt flags */
+};
+
+static int setup_pmic_voltages(void)
+{
+       int ret;
+       unsigned char value;
+       int i;
+
+       ret = i2c_probe(CONFIG_SYS_I2C_SLAVE);
+       if (ret != 0) {
+               printf("Failed to initialize I2C\n");
+               return ret;
+       }
+
+       ret = i2c_read(CONFIG_SYS_I2C_SLAVE, 0x11, 1, &value, 1);
+       if (ret) {
+               printf("%s: i2c_read error: %d\n", __func__, ret);
+               return ret;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(ltc3589_regs); i++) {
+               ret = i2c_read(CONFIG_SYS_I2C_SLAVE, ltc3589_regs[i].addr, 1,
+                               &value, 1);
+               debug("Writing %02x to reg %02x (%02x)\n",
+                       ltc3589_regs[i].val, ltc3589_regs[i].addr, value);
+               ret = i2c_write(CONFIG_SYS_I2C_SLAVE, ltc3589_regs[i].addr, 1,
+                               &ltc3589_regs[i].val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, ltc3589_regs[i].addr, ret);
+                       return ret;
+               }
+       }
+       printf("VDDCORE set to %umV\n",
+               DIV_ROUND(vref_to_vout(regval_to_mV(VDD_CORE_VAL), 3), 10));
+
+       printf("VDDSOC  set to %umV\n",
+               DIV_ROUND(vref_to_vout(regval_to_mV(VDD_SOC_VAL), 4), 10));
+       return 0;
+}
+
+static struct {
+       u32 max_freq;
+       u32 mV;
+} tx53_core_voltages[] = {
+       { 800000000, 1100, },
+       { 1000000000, 1240, },
+       { 1200000000, 1350, },
+};
+
+int adjust_core_voltage(u32 freq)
+{
+       int ret;
+       int i;
+
+       printf("%s@%d\n", __func__, __LINE__);
+
+       for (i = 0; i < ARRAY_SIZE(tx53_core_voltages); i++) {
+               if (freq <= tx53_core_voltages[i].max_freq) {
+                       int retries = 0;
+                       const int max_tries = 10;
+                       const int delay_us = 1;
+                       u32 mV = tx53_core_voltages[i].mV;
+                       u8 val = mV_to_regval(vout_to_vref(mV * 10, 3));
+                       u8 v;
+
+                       debug("regval[%umV]=%02x\n", mV, val);
+
+                       ret = i2c_read(CONFIG_SYS_I2C_SLAVE, LTC3589_B1DTV1, 1,
+                               &v, 1);
+                       if (ret) {
+                               printf("%s: failed to read PMIC register %02x: %d\n",
+                                       __func__, LTC3589_B1DTV1, ret);
+                               return ret;
+                       }
+                       debug("Changing reg %02x from %02x to %02x\n",
+                               LTC3589_B1DTV1, v, (v & ~0x1f) |
+                               mV_to_regval(vout_to_vref(mV * 10, 3)));
+                       v &= ~0x1f;
+                       v |= mV_to_regval(vout_to_vref(mV * 10, 3));
+                       ret = i2c_write(CONFIG_SYS_I2C_SLAVE, LTC3589_B1DTV1, 1,
+                                       &v, 1);
+                       if (ret) {
+                               printf("%s: failed to write PMIC register %02x: %d\n",
+                                       __func__, LTC3589_B1DTV1, ret);
+                               return ret;
+                       }
+                       ret = i2c_read(CONFIG_SYS_I2C_SLAVE, LTC3589_VCCR, 1,
+                                       &v, 1);
+                       if (ret) {
+                               printf("%s: failed to read PMIC register %02x: %d\n",
+                                       __func__, LTC3589_VCCR, ret);
+                               return ret;
+                       }
+                       v |= 0x1;
+                       ret = i2c_write(CONFIG_SYS_I2C_SLAVE, LTC3589_VCCR, 1,
+                                       &v, 1);
+                       if (ret) {
+                               printf("%s: failed to write PMIC register %02x: %d\n",
+                                       __func__, LTC3589_VCCR, ret);
+                               return ret;
+                       }
+                       for (retries = 0; retries < max_tries; retries++) {
+                               ret = i2c_read(CONFIG_SYS_I2C_SLAVE,
+                                       LTC3589_VCCR, 1, &v, 1);
+                               if (ret) {
+                                       printf("%s: failed to read PMIC register %02x: %d\n",
+                                               __func__, LTC3589_VCCR, ret);
+                                       return ret;
+                               }
+                               if (!(v & 1))
+                                       break;
+                               udelay(delay_us);
+                       }
+                       if (v & 1) {
+                               printf("change of VDDCORE did not complete after %uµs\n",
+                                       retries * delay_us);
+                               return -ETIMEDOUT;
+                       }
+
+                       printf("VDDCORE set to %umV after %u loops\n",
+                               DIV_ROUND(vref_to_vout(regval_to_mV(val & 0x1f), 3),
+                                       10), retries);
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+int board_early_init_f(void)
+{
+       struct mxc_ccm_reg *ccm_regs = (void *)CCM_BASE_ADDR;
+
+       gpio_request_array(tx53_gpios, ARRAY_SIZE(tx53_gpios));
+       imx_iomux_v3_setup_multiple_pads(tx53_pads, ARRAY_SIZE(tx53_pads));
+
+       writel(0x77777777, AIPS1_BASE_ADDR + 0x00);
+       writel(0x77777777, AIPS1_BASE_ADDR + 0x04);
+
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x40);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x44);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x48);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x4c);
+       writel(0x00000000, AIPS1_BASE_ADDR + 0x50);
+
+       writel(0x77777777, AIPS2_BASE_ADDR + 0x00);
+       writel(0x77777777, AIPS2_BASE_ADDR + 0x04);
+
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x40);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x44);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x48);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x4c);
+       writel(0x00000000, AIPS2_BASE_ADDR + 0x50);
+
+       writel(0xffcf0fff, &ccm_regs->CCGR0);
+       writel(0x000fffcf, &ccm_regs->CCGR1);
+       writel(0x033c0000, &ccm_regs->CCGR2);
+       writel(0x000000ff, &ccm_regs->CCGR3);
+       writel(0x00000000, &ccm_regs->CCGR4);
+       writel(0x00fff033, &ccm_regs->CCGR5);
+       writel(0x0f00030f, &ccm_regs->CCGR6);
+       writel(0xfff00000, &ccm_regs->CCGR7);
+       writel(0x00000000, &ccm_regs->cmeor);
+
+       return 0;
+}
+
+int board_init(void)
+{
+       int ret;
+
+       /* Address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
+
+       if (ctrlc() || (wrsr & WRSR_TOUT)) {
+               if (wrsr & WRSR_TOUT)
+                       printf("WDOG RESET detected; Skipping PMIC setup\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+               return 1;
+       }
+
+       ret = setup_pmic_voltages();
+       if (ret) {
+               printf("Failed to setup PMIC voltages\n");
+               hang();
+       }
+       return 0;
+}
+
+int dram_init(void)
+{
+       int ret;
+
+       /*
+        * U-Boot doesn't support RAM banks with intervening holes,
+        * so let U-Boot only know about the first bank for its
+        * internal data structures. The size reported to Linux is
+        * determined from the individual bank sizes.
+        */
+       gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, SZ_1G);
+
+       ret = mxc_set_clock(CONFIG_SYS_MX5_HCLK,
+               CONFIG_SYS_SDRAM_CLK, MXC_DDR_CLK);
+       if (ret)
+               printf("%s: Failed to set DDR clock to %u MHz: %d\n", __func__,
+                       CONFIG_SYS_SDRAM_CLK, ret);
+       else
+               debug("%s: DDR clock set to %u.%03u MHz (desig.: %u.000 MHz)\n",
+                       __func__, mxc_get_clock(MXC_DDR_CLK) / 1000000,
+                       mxc_get_clock(MXC_DDR_CLK) / 1000 % 1000,
+                       CONFIG_SYS_SDRAM_CLK);
+       return ret;
+}
+
+void dram_init_banksize(void)
+{
+       long total_size = gd->ram_size;
+
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = gd->ram_size;
+
+#if CONFIG_NR_DRAM_BANKS > 1
+       gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2, SZ_1G);
+
+       if (gd->bd->bi_dram[1].size) {
+               debug("Found %luMiB SDRAM in bank 2\n",
+                       gd->bd->bi_dram[1].size / SZ_1M);
+               gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+               total_size += gd->bd->bi_dram[1].size;
+       }
+#endif
+       if (total_size != CONFIG_SYS_SDRAM_SIZE)
+               printf("WARNING: SDRAM size mismatch: %uMiB configured; %luMiB detected\n",
+                       CONFIG_SYS_SDRAM_SIZE / SZ_1M, total_size / SZ_1M);
+}
+
+#ifdef CONFIG_CMD_MMC
+static const iomux_v3_cfg_t mmc0_pads[] = {
+       MX53_PAD_SD1_CMD__ESDHC1_CMD | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_CLK__ESDHC1_CLK | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_DATA0__ESDHC1_DAT0 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_DATA1__ESDHC1_DAT1 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_DATA2__ESDHC1_DAT2 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD1_DATA3__ESDHC1_DAT3 | TX53_SDHC_PAD_CTRL,
+       /* SD1 CD */
+       MX53_PAD_EIM_D24__GPIO3_24 | MX53_GPIO_PAD_CTRL,
+};
+
+static const iomux_v3_cfg_t mmc1_pads[] = {
+       MX53_PAD_SD2_CMD__ESDHC2_CMD | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_CLK__ESDHC2_CLK | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_DATA0__ESDHC2_DAT0 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_DATA1__ESDHC2_DAT1 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_DATA2__ESDHC2_DAT2 | TX53_SDHC_PAD_CTRL,
+       MX53_PAD_SD2_DATA3__ESDHC2_DAT3 | TX53_SDHC_PAD_CTRL,
+       /* SD2 CD */
+       MX53_PAD_EIM_D25__GPIO3_25 | MX53_GPIO_PAD_CTRL,
+};
+
+static struct tx53_esdhc_cfg {
+       const iomux_v3_cfg_t *pads;
+       int num_pads;
+       struct fsl_esdhc_cfg cfg;
+       int cd_gpio;
+} tx53_esdhc_cfg[] = {
+       {
+               .pads = mmc0_pads,
+               .num_pads = ARRAY_SIZE(mmc0_pads),
+               .cfg = {
+                       .esdhc_base = (void __iomem *)MMC_SDHC1_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(3, 24),
+       },
+       {
+               .pads = mmc1_pads,
+               .num_pads = ARRAY_SIZE(mmc1_pads),
+               .cfg = {
+                       .esdhc_base = (void __iomem *)MMC_SDHC2_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(3, 25),
+       },
+};
+
+static inline struct tx53_esdhc_cfg *to_tx53_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
+{
+       return container_of(cfg, struct tx53_esdhc_cfg, cfg);
+}
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct tx53_esdhc_cfg *cfg = to_tx53_esdhc_cfg(mmc->priv);
+
+       if (cfg->cd_gpio < 0)
+               return cfg->cd_gpio;
+
+       debug("SD card %d is %spresent\n",
+               cfg - tx53_esdhc_cfg,
+               gpio_get_value(cfg->cd_gpio) ? "NOT " : "");
+       return !gpio_get_value(cfg->cd_gpio);
+}
+
+int board_mmc_init(bd_t *bis)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(tx53_esdhc_cfg); i++) {
+               struct mmc *mmc;
+               struct tx53_esdhc_cfg *cfg = &tx53_esdhc_cfg[i];
+               int ret;
+
+               imx_iomux_v3_setup_multiple_pads(cfg->pads, cfg->num_pads);
+               cfg->cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+
+               ret = gpio_request_one(cfg->cd_gpio,
+                               GPIOFLAG_INPUT, "MMC CD");
+               if (ret) {
+                       printf("Error %d requesting GPIO%d_%d\n",
+                               ret, cfg->cd_gpio / 32, cfg->cd_gpio % 32);
+                       continue;
+               }
+
+               debug("%s: Initializing MMC slot %d\n", __func__, i);
+               fsl_esdhc_initialize(bis, &cfg->cfg);
+
+               mmc = find_mmc_device(i);
+               if (mmc == NULL)
+                       continue;
+               if (board_mmc_getcd(mmc) > 0)
+                       mmc_init(mmc);
+       }
+       return 0;
+}
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_FEC_MXC
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+       int i;
+       struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
+       struct fuse_bank *bank = &iim->bank[1];
+       struct fuse_bank1_regs *fuse = (struct fuse_bank1_regs *)bank->fuse_regs;
+
+       if (dev_id > 0)
+               return;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               mac[i] = readl(&fuse->mac_addr[i]);
+}
+
+#define FEC_PAD_CTL    (PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
+                       PAD_CTL_SRE_FAST)
+#define FEC_PAD_CTL2   (PAD_CTL_DVS | PAD_CTL_SRE_FAST)
+#define GPIO_PAD_CTL   (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       /* delay at least 21ms for the PHY internal POR signal to deassert */
+       udelay(22000);
+
+       /* Deassert RESET to the external phy */
+       gpio_set_value(TX53_FEC_RST_GPIO, 1);
+
+       ret = cpu_eth_init(bis);
+       if (ret)
+               printf("cpu_eth_init() failed: %d\n", ret);
+
+       return ret;
+}
+#endif /* CONFIG_FEC_MXC */
+
+enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+};
+
+void show_activity(int arg)
+{
+       static int led_state = LED_STATE_INIT;
+       static ulong last;
+
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX53_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+       } else {
+               if (get_timer(last) > CONFIG_SYS_HZ) {
+                       last = get_timer(0);
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX53_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX53_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+}
+
+static const iomux_v3_cfg_t stk5_pads[] = {
+       /* SW controlled LED on STK5 baseboard */
+       MX53_PAD_EIM_A18__GPIO2_20,
+
+       /* I2C bus on DIMM pins 40/41 */
+       MX53_PAD_GPIO_6__I2C3_SDA | MX53_GPIO_PAD_CTRL,
+       MX53_PAD_GPIO_3__I2C3_SCL | MX53_GPIO_PAD_CTRL,
+
+       /* TSC200x PEN IRQ */
+       MX53_PAD_EIM_D26__GPIO3_26 | MX53_GPIO_PAD_CTRL,
+
+       /* EDT-FT5x06 Polytouch panel */
+       MX53_PAD_NANDF_CS2__GPIO6_15 | MX53_GPIO_PAD_CTRL, /* IRQ */
+       MX53_PAD_EIM_A16__GPIO2_22 | MX53_GPIO_PAD_CTRL, /* RESET */
+       MX53_PAD_EIM_A17__GPIO2_21 | MX53_GPIO_PAD_CTRL, /* WAKE */
+
+       /* USBH1 */
+       MX53_PAD_EIM_D31__GPIO3_31 | MX53_GPIO_PAD_CTRL, /* VBUSEN */
+       MX53_PAD_EIM_D30__GPIO3_30 | MX53_GPIO_PAD_CTRL, /* OC */
+       /* USBOTG */
+       MX53_PAD_GPIO_7__GPIO1_7, /* VBUSEN */
+       MX53_PAD_GPIO_8__GPIO1_8, /* OC */
+
+       /* DS1339 Interrupt */
+       MX53_PAD_DI0_PIN4__GPIO4_20 | MX53_GPIO_PAD_CTRL,
+};
+
+static const struct gpio stk5_gpios[] = {
+       { TX53_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
+
+       { IMX_GPIO_NR(1, 8), GPIOFLAG_INPUT, "USBOTG OC", },
+       { IMX_GPIO_NR(1, 7), GPIOFLAG_OUTPUT_INIT_LOW, "USBOTG VBUS enable", },
+       { IMX_GPIO_NR(3, 30), GPIOFLAG_INPUT, "USBH1 OC", },
+       { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
+};
+
+#ifdef CONFIG_LCD
+static u16 tx53_cmap[256];
+vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1600,
+       .vl_row = 1200,
+
+       .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx53_cmap,
+};
+
+static struct fb_videomode tx53_fb_modes[] = {
+#ifndef CONFIG_SYS_LVDS_IF
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+#else
+       {
+               /* HannStar HSD100PXN1
+                * 202.7m mm x 152.06 mm display area.
+                */
+               .name           = "HSD100PXN1",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = KHZ2PICOS(65000),
+               .left_margin    = 0,
+               .hsync_len      = 0,
+               .right_margin   = 320,
+               .upper_margin   = 0,
+               .vsync_len      = 0,
+               .lower_margin   = 38,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+#endif
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+};
+
+static int lcd_enabled = 1;
+static int lcd_bl_polarity;
+
+static int lcd_backlight_polarity(void)
+{
+       return lcd_bl_polarity;
+}
+
+void lcd_enable(void)
+{
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+
+       if (lcd_enabled) {
+               karo_load_splashimage(1);
+
+               debug("Switching LCD on\n");
+               gpio_set_value(TX53_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX53_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX53_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+}
+
+void lcd_disable(void)
+{
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               ipuv3_fb_shutdown();
+       }
+}
+
+void lcd_panel_disable(void)
+{
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX53_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX53_LCD_RST_GPIO, 0);
+               gpio_set_value(TX53_LCD_PWR_GPIO, 0);
+       }
+}
+
+static const iomux_v3_cfg_t stk5_lcd_pads[] = {
+       /* LCD RESET */
+       MX53_PAD_EIM_D29__GPIO3_29 | MX53_GPIO_PAD_CTRL,
+       /* LCD POWER_ENABLE */
+       MX53_PAD_EIM_EB3__GPIO2_31 | MX53_GPIO_PAD_CTRL,
+       /* LCD Backlight (PWM) */
+       MX53_PAD_GPIO_1__GPIO1_1 | MX53_GPIO_PAD_CTRL,
+
+       /* Display */
+#ifndef CONFIG_SYS_LVDS_IF
+       /* LCD option */
+       MX53_PAD_DI0_DISP_CLK__IPU_DI0_DISP_CLK,
+       MX53_PAD_DI0_PIN15__IPU_DI0_PIN15,
+       MX53_PAD_DI0_PIN2__IPU_DI0_PIN2,
+       MX53_PAD_DI0_PIN3__IPU_DI0_PIN3,
+       MX53_PAD_DISP0_DAT0__IPU_DISP0_DAT_0,
+       MX53_PAD_DISP0_DAT1__IPU_DISP0_DAT_1,
+       MX53_PAD_DISP0_DAT2__IPU_DISP0_DAT_2,
+       MX53_PAD_DISP0_DAT3__IPU_DISP0_DAT_3,
+       MX53_PAD_DISP0_DAT4__IPU_DISP0_DAT_4,
+       MX53_PAD_DISP0_DAT5__IPU_DISP0_DAT_5,
+       MX53_PAD_DISP0_DAT6__IPU_DISP0_DAT_6,
+       MX53_PAD_DISP0_DAT7__IPU_DISP0_DAT_7,
+       MX53_PAD_DISP0_DAT8__IPU_DISP0_DAT_8,
+       MX53_PAD_DISP0_DAT9__IPU_DISP0_DAT_9,
+       MX53_PAD_DISP0_DAT10__IPU_DISP0_DAT_10,
+       MX53_PAD_DISP0_DAT11__IPU_DISP0_DAT_11,
+       MX53_PAD_DISP0_DAT12__IPU_DISP0_DAT_12,
+       MX53_PAD_DISP0_DAT13__IPU_DISP0_DAT_13,
+       MX53_PAD_DISP0_DAT14__IPU_DISP0_DAT_14,
+       MX53_PAD_DISP0_DAT15__IPU_DISP0_DAT_15,
+       MX53_PAD_DISP0_DAT16__IPU_DISP0_DAT_16,
+       MX53_PAD_DISP0_DAT17__IPU_DISP0_DAT_17,
+       MX53_PAD_DISP0_DAT18__IPU_DISP0_DAT_18,
+       MX53_PAD_DISP0_DAT19__IPU_DISP0_DAT_19,
+       MX53_PAD_DISP0_DAT20__IPU_DISP0_DAT_20,
+       MX53_PAD_DISP0_DAT21__IPU_DISP0_DAT_21,
+       MX53_PAD_DISP0_DAT22__IPU_DISP0_DAT_22,
+       MX53_PAD_DISP0_DAT23__IPU_DISP0_DAT_23,
+#else
+       /* LVDS option */
+       MX53_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3,
+       MX53_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2,
+       MX53_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK,
+       MX53_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1,
+       MX53_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0,
+       MX53_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3,
+       MX53_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK,
+       MX53_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2,
+       MX53_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1,
+       MX53_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0,
+#endif
+};
+
+static const struct gpio stk5_lcd_gpios[] = {
+       { TX53_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
+       { TX53_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
+       { TX53_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+};
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = &tx53_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+       int pix_fmt;
+       int lcd_bus_width;
+       ipu_di_clk_parent_t di_clk_parent = is_lvds() ? DI_PCLK_LDB : DI_PCLK_PLL3;
+       unsigned long di_clk_rate = 65000000;
+
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+
+       karo_fdt_move_fdt();
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 32:
+                                       case 24:
+                                               if (is_lvds())
+                                                       pix_fmt = IPU_PIX_FMT_LVDS888;
+                                               /* fallthru */
+                                       case 16:
+                                       case 8:
+                                               color_depth = val;
+                                               break;
+
+                                       case 18:
+                                               if (is_lvds()) {
+                                                       color_depth = val;
+                                                       break;
+                                               }
+                                               /* fallthru */
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx53_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
+               panel_info.vl_bpix = LCD_COLOR32;
+       }
+
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
+                               1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000);
+
+       if (p != &fb_mode) {
+               int ret;
+
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
+                                       ARRAY_SIZE(stk5_lcd_pads));
+
+       lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24);
+       switch (lcd_bus_width) {
+       case 24:
+               pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS888 : IPU_PIX_FMT_RGB24;
+               break;
+
+       case 18:
+               pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS666 : IPU_PIX_FMT_RGB666;
+               break;
+
+       case 16:
+               if (!is_lvds()) {
+                       pix_fmt = IPU_PIX_FMT_RGB565;
+                       break;
+               }
+               /* fallthru */
+       default:
+               lcd_enabled = 0;
+               printf("Invalid %s bus width: %d\n", is_lvds() ? "LVDS" : "LCD",
+                       lcd_bus_width);
+               return;
+       }
+       if (is_lvds()) {
+               int lvds_mapping = karo_fdt_get_lvds_mapping(working_fdt, 0);
+               int lvds_chan_mask = karo_fdt_get_lvds_channels(working_fdt);
+               uint32_t gpr2;
+
+               if (lvds_chan_mask == 0) {
+                       printf("No LVDS channel active\n");
+                       lcd_enabled = 0;
+                       return;
+               }
+
+               gpr2 = (lvds_mapping << 6) | (lvds_mapping << 8);
+               if (lcd_bus_width == 24)
+                       gpr2 |= (1 << 5) | (1 << 7);
+               gpr2 |= (lvds_chan_mask & 1) ? 1 << 0 : 0;
+               gpr2 |= (lvds_chan_mask & 2) ? 3 << 2 : 0;
+               debug("writing %08x to GPR2[%08x]\n", gpr2, IOMUXC_BASE_ADDR + 8);
+               writel(gpr2, IOMUXC_BASE_ADDR + 8);
+       }
+       if (karo_load_splashimage(0) == 0) {
+               int ret;
+
+               gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3M;
+
+               debug("Initializing LCD controller\n");
+               ret = ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
+               if (ret) {
+                       printf("Failed to initialize FB driver: %d\n", ret);
+                       lcd_enabled = 0;
+               }
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+}
+#else
+#define lcd_enabled 0
+#endif /* CONFIG_LCD */
+
+static void stk5_board_init(void)
+{
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+}
+
+static void stk5v3_board_init(void)
+{
+       stk5_board_init();
+}
+
+static void stk5v5_board_init(void)
+{
+       stk5_board_init();
+
+       gpio_request_one(IMX_GPIO_NR(4, 21), GPIOFLAG_OUTPUT_INIT_HIGH,
+                       "Flexcan Transceiver");
+       imx_iomux_v3_setup_pad(MX53_PAD_DISP0_DAT0__GPIO4_21);
+}
+
+static void tx53_set_cpu_clock(void)
+{
+       unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+
+       if (cpu_clk == 0 || cpu_clk == mxc_get_clock(MXC_ARM_CLK) / 1000000)
+               return;
+
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               printf("%s detected; skipping cpu clock change\n",
+                       (wrsr & WRSR_TOUT) ? "WDOG RESET" : "<CTRL-C>");
+               return;
+       }
+
+       if (mxc_set_clock(CONFIG_SYS_MX5_HCLK, cpu_clk, MXC_ARM_CLK) == 0) {
+               cpu_clk = mxc_get_clock(MXC_ARM_CLK);
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       cpu_clk / 1000000, cpu_clk / 1000 % 1000);
+       } else {
+               printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk);
+       }
+}
+
+static void tx53_init_mac(void)
+{
+       u8 mac[ETH_ALEN];
+
+       imx_get_mac_from_fuse(0, mac);
+       if (!is_valid_ether_addr(mac)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+
+       printf("MAC addr from fuse: %pM\n", mac);
+       eth_setenv_enetaddr("ethaddr", mac);
+}
+
+int board_late_init(void)
+{
+       int ret = 0;
+       const char *baseboard;
+
+       env_cleanup();
+
+       tx53_set_cpu_clock();
+
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (wrsr & WRSR_TOUT)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
+
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+
+       printf("Baseboard: %s\n", baseboard);
+
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       const char *otg_mode = getenv("otg_mode");
+
+                       if (otg_mode && strcmp(otg_mode, "host") == 0) {
+                               printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
+                                       otg_mode, baseboard);
+                               setenv("otg_mode", "none");
+                       }
+                       stk5v5_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+
+exit:
+       tx53_init_mac();
+
+       gpio_set_value(TX53_RESET_OUT_GPIO, 1);
+       clear_ctrlc();
+       return ret;
+}
+
+int checkboard(void)
+{
+       tx53_print_cpuinfo();
+#if CONFIG_SYS_SDRAM_SIZE < SZ_1G
+       printf("Board: Ka-Ro TX53-8%d3%c\n",
+               is_lvds(), '0' + CONFIG_SYS_SDRAM_SIZE / SZ_1G);
+#elif CONFIG_SYS_SDRAM_SIZE < SZ_2G
+       printf("Board: Ka-Ro TX53-1%d3%c\n",
+               is_lvds() + 2, '0' + CONFIG_SYS_SDRAM_SIZE / SZ_1G);
+#else
+       printf("Board: Ka-Ro TX53-123%c\n",
+               '0' + CONFIG_SYS_SDRAM_SIZE / SZ_1G);
+#endif
+       return 0;
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+#ifdef CONFIG_FDT_FIXUP_PARTITIONS
+#include <jffs2/jffs2.h>
+#include <mtd_node.h>
+static struct node_info nodes[] = {
+       { "fsl,imx53-nand", MTD_DEV_TYPE_NAND, },
+};
+#else
+#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+#endif
+
+#ifdef CONFIG_SYS_TX53_HWREV_2
+static void tx53_fixup_rtc(void *blob)
+{
+       karo_fdt_del_prop(blob, "dallas,ds1339", 0x68, "interrupt-parent");
+       karo_fdt_del_prop(blob, "dallas,ds1339", 0x68, "interrupts");
+}
+#else
+static inline void tx53_fixup_rtc(void *blob)
+{
+}
+#endif /* CONFIG_SYS_TX53_HWREV_2 */
+
+static const char *tx53_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "eeti,egalax_ts",
+};
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+
+       ret = fdt_increase_size(blob, 4096);
+       if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
+               return ret;
+       }
+       if (stk5_v5)
+               karo_fdt_enable_node(blob, "stk5led", 0);
+
+       fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+       fdt_fixup_ethernet(blob);
+
+       karo_fdt_fixup_touchpanel(blob, tx53_touchpanels,
+                               ARRAY_SIZE(tx53_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+       tx53_fixup_rtc(blob);
+       karo_fdt_update_fb_mode(blob, video_mode);
+
+       return 0;
+}
+#endif /* CONFIG_OF_BOARD_SETUP */
diff --git a/board/karo/tx53/u-boot.lds b/board/karo/tx53/u-boot.lds
new file mode 100644 (file)
index 0000000..9de3dc5
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * (C) Copyright 2012  Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+       . = 0x00000000;
+       .text :
+       {
+               *(.__image_copy_start)
+               *(.vectors)
+               CPUDIR/start.o (.text*)
+               . = 0x400;
+               KEEP(BOARDDIR/lowlevel_init.o (.text*))
+               *(.text*)
+       }
+
+#if defined(CONFIG_ARMV7_NONSEC) || defined(CONFIG_ARMV7_VIRT) || defined(CONFIG_ARMV7_PSCI)
+
+#ifndef CONFIG_ARMV7_SECURE_BASE
+#define CONFIG_ARMV7_SECURE_BASE
+#endif
+
+       .__secure_start : {
+               . = ALIGN(0x1000);
+               *(.__secure_start)
+       }
+
+       .secure_text CONFIG_ARMV7_SECURE_BASE :
+               AT(ADDR(.__secure_start) + SIZEOF(.__secure_start))
+       {
+               *(._secure.text)
+       }
+
+       . = LOADADDR(.__secure_start) +
+               SIZEOF(.__secure_start) +
+               SIZEOF(.secure_text);
+
+       __secure_end_lma = .;
+       .__secure_end : AT(__secure_end_lma) {
+               *(.__secure_end)
+               LONG(0x1d1071c);        /* Must output something to reset LMA */
+       }
+#endif
+
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+       . = ALIGN(4);
+       .data : {
+               *(.data*)
+       }
+
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+
+       . = ALIGN(4);
+       .image_copy_end :
+       {
+               *(.__image_copy_end)
+       }
+
+       .rel_dyn_start :
+       {
+               *(.__rel_dyn_start)
+       }
+
+       .rel.dyn :
+       {
+               *(.rel*)
+       }
+
+       .rel_dyn_end :
+       {
+               *(.__rel_dyn_end)
+       }
+
+       /* Workaround for an apparent bug in i.MX53 ROM Code,
+        * that skips loading the last block if it doesn't
+        * end on a 4KiB boundary.
+        */
+
+       . = ALIGN(4096);
+       .uboot_img_end :
+       {
+               *(.__uboot_img_end)
+       }
+
+       _image_binary_end = .;
+
+/*
+ * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+ * __bss_base and __bss_limit are for linker only (overlay ordering)
+ */
+
+       .bss_start __rel_dyn_start (OVERLAY) : {
+               KEEP(*(.__bss_start));
+               __bss_base = .;
+       }
+
+       .bss __bss_base (OVERLAY) : {
+               *(.bss*)
+               . = ALIGN(4);
+               __bss_limit = .;
+       }
+       .bss_end __bss_limit (OVERLAY) : {
+               KEEP(*(.__bss_end));
+       }
+
+       .dynsym _image_binary_end : { *(.dynsym) }
+       .dynbss : { *(.dynbss) }
+       .dynstr : { *(.dynstr*) }
+       .dynamic : { *(.dynamic*) }
+       .plt : { *(.plt*) }
+       .interp : { *(.interp*) }
+       .gnu.hash : { *(.gnu.hash) }
+       .gnu : { *(.gnu*) }
+       .ARM.exidx : { *(.ARM.exidx*) }
+       .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
+}
diff --git a/board/karo/tx6/Kconfig b/board/karo/tx6/Kconfig
new file mode 100644 (file)
index 0000000..c848d59
--- /dev/null
@@ -0,0 +1,170 @@
+if TARGET_TX6
+
+config MX6
+       bool
+       default y
+
+config MX6Q
+       bool
+
+config MX6DL
+       bool
+
+config MX6QDL
+       bool
+
+config MX6S
+       bool
+
+config MX6SL
+       bool
+
+config MX6SX
+       bool
+
+config SYS_BOARD
+       default "tx6"
+
+config SYS_VENDOR
+       default "karo"
+
+config SYS_SOC
+       default "mx6"
+
+config SYS_CONFIG_NAME
+       default "tx6"
+
+config CMD_ROMUPDATE
+       bool
+
+config TX6
+       bool
+       default y
+       select MX6
+       select CMD_BMP if LCD
+       select CMD_BOOTCE
+       select CMD_BOOTZ
+       select CMD_CACHE
+       select CMD_I2C if I2C
+       select CMD_MEMTEST
+       select CMD_TIME
+       select DM
+       select DM_GPIO
+       select SYS_I2C
+       select SYS_I2C_MXC
+       select GET_FEC_MAC_ADDR_FROM_IIM
+       select OF_LIBFDT
+
+config TX6_NAND
+       bool
+       default ! TX6_EMMC
+       select CMD_NAND
+       select CMD_NAND_TRIMFFS
+       select CMD_MTDPARTS
+       select CMD_ROMUPDATE
+       select FDT_FIXUP_PARTITIONS if OF_LIBFDT
+       select MTD_PARTITIONS
+       select NAND_MXS_NO_BBM_SWAP if NAND_MXS
+       select SYS_NAND_USE_FLASH_BBT if NAND_MXS
+       select APBH_DMA
+       select APBH_DMA_BURST
+       select APBH_DMA_BURST8
+       select MTD_DEVICE
+
+config TX6_EMMC
+       bool
+       select SUPPORT_EMMC_BOOT
+
+#
+# variables selected depending on module variant
+#
+config SYS_LVDS_IF
+       bool
+
+config SYS_SDRAM_BUS_WIDTH_16
+       bool
+
+config SYS_SDRAM_BUS_WIDTH_32
+       bool
+
+
+choice
+       prompt "TX6 module variant"
+
+config TARGET_TX6Q_10X0
+       bool "TX6Q-1010 and TX6Q-1030"
+       select MX6Q
+
+config TARGET_TX6Q_1020
+       bool "TX6Q-1020"
+       select MX6Q
+       select TX6_EMMC
+       select TX6_REV_2
+
+config TARGET_TX6Q_11X0
+       bool "TX6Q-1110 and TX6Q-1130"
+       select MX6Q
+       select SYS_LVDS_IF
+       
+config TARGET_TX6S_8034
+       bool "TX6S-8034"
+       select MX6S
+       select SYS_SDRAM_BUS_WIDTH_16
+
+config TARGET_TX6S_8035
+       bool "TX6S-8035"
+       select MX6S
+       select TX6_EMMC
+       select SYS_SDRAM_BUS_WIDTH_32
+
+config TARGET_TX6U_8010
+       bool "TX6U-8010 and TX6U-8030"
+       select MX6DL
+
+config TARGET_TX6U_8011
+       bool "TX6U-8011"
+       select MX6DL
+       select SYS_SDRAM_BUS_WIDTH_32
+       select TX6_REV_1
+
+config TARGET_TX6U_8012
+       bool "TX6U-8012"
+       select MX6DL
+       select TX6_REV_1
+
+config TARGET_TX6U_81X0
+       bool "TX6U-8110 and TX6U-8130"
+       select MX6DL
+       select SYS_LVDS_IF
+
+config TARGET_TX6U_8111
+       bool "TX6U-8111"
+       select MX6DL
+       select SYS_SDRAM_BUS_WIDTH_32
+       select SYS_LVDS_IF
+       select TX6_REV_1
+
+config TARGET_TX6U_8033
+       bool "TX6U-8033"
+       select MX6DL
+       select TX6_EMMC
+       select TX6_REV_3
+
+endchoice
+
+choice
+       prompt "U-Boot image variant"
+       default TX6_UBOOT
+
+config TX6_UBOOT
+       bool "Standard U-Boot image"
+
+config TX6_UBOOT_MFG
+       bool "U-Boot image for use with Freescale's MfGTool"
+
+config TX6_UBOOT_NOENV
+       bool "U-Boot using only built-in environment"
+
+endchoice
+
+endif
diff --git a/board/karo/tx6/Makefile b/board/karo/tx6/Makefile
new file mode 100644 (file)
index 0000000..74d5c0c
--- /dev/null
@@ -0,0 +1,14 @@
+#
+# (C) Copyright 2015 Lothar Waßmann <LW@KARO-electronics.de>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+LDSCRIPT := $(BOARDDIR)/u-boot.lds
+
+obj-y                          += lowlevel_init.o pmic.o tx6qdl.o
+obj-$(CONFIG_LTC3676)          += ltc3676.o
+obj-$(CONFIG_RN5T567)          += rn5t567.o
+obj-$(CONFIG_RN5T618)          += rn5t618.o
+
+obj-$(CONFIG_CMD_ROMUPDATE)    += flash.o
diff --git a/board/karo/tx6/config.mk b/board/karo/tx6/config.mk
new file mode 100644 (file)
index 0000000..c1215d5
--- /dev/null
@@ -0,0 +1,57 @@
+# stack is allocated below CONFIG_SYS_TEXT_BASE
+CONFIG_SYS_TEXT_BASE := 0x10100000
+
+__HAVE_ARCH_GENERIC_BOARD := y
+
+LOGO_BMP = logos/karo.bmp
+#PLATFORM_CPPFLAGS += -DDEBUG
+#PLATFORM_CPPFLAGS += -Wno-unused-but-set-variable
+PLATFORM_CPPFLAGS += -Werror
+
+ifeq ($(CONFIG_TX6_NAND),y)
+# calculate U_BOOT_IMG_SIZE to be at least 3 eraseblocks larger than the maximum expected image size
+CONFIG_SYS_NAND_BLOCK_SIZE := 131072
+ifeq ($(CONFIG_SYS_NAND_BLOCKS),)
+CONFIG_SYS_NAND_BLOCKS := 1024
+endif
+ifneq ($(CONFIG_SYS_NAND_BLOCK_SIZE),)
+CONFIG_U_BOOT_IMG_SIZE := $(shell echo 'e=$(CONFIG_SYS_NAND_BLOCK_SIZE);s=640*1024;s + (e - s % e) % e + 3*e' | bc)
+CONFIG_SYS_USERFS_SIZE := $(shell expr \( $(CONFIG_SYS_NAND_BLOCKS) - 12 \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) - $(CONFIG_U_BOOT_IMG_SIZE) - 38 \* 1048576)
+CONFIG_SYS_USERFS_SIZE2 := $(shell expr \( $(CONFIG_SYS_NAND_BLOCKS) - 15 \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) - $(CONFIG_U_BOOT_IMG_SIZE) - 38 \* 1048576)
+CONFIG_SYS_NAND_BBT_BLOCKS := 4
+CONFIG_SYS_NAND_DTB_BLOCKS := 4
+
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BLOCKS=$(CONFIG_SYS_NAND_BLOCKS)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BLOCK_SIZE=$(CONFIG_SYS_NAND_BLOCK_SIZE)
+PLATFORM_CPPFLAGS += -DCONFIG_U_BOOT_IMG_SIZE=$(CONFIG_U_BOOT_IMG_SIZE)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_U_BOOT_PART_SIZE=$(shell printf "%uk" `expr $(CONFIG_U_BOOT_IMG_SIZE) / 1024`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_U_BOOT_OFFS=$(shell printf "0x%x" `expr $(CONFIG_SYS_NAND_BLOCK_SIZE)`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_ENV_PART_SIZE=$(shell printf "%uk" `expr 3 \* $(CONFIG_SYS_NAND_BLOCK_SIZE) / 1024`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_USERFS_PART_SIZE=$(shell printf "%uk" `expr $(CONFIG_SYS_USERFS_SIZE) / 1024`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_USERFS_PART_SIZE2=$(shell printf "%uk" `expr $(CONFIG_SYS_USERFS_SIZE) / 1024`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_DTB_PART_SIZE=$(shell printf "%uk" `expr $(CONFIG_SYS_NAND_BLOCK_SIZE) \* $(CONFIG_SYS_NAND_BBT_BLOCKS) / 1024`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_DTB_OFFSET=$(shell printf "0x%x" `expr \( $(CONFIG_SYS_NAND_BLOCKS) - $(CONFIG_SYS_NAND_DTB_BLOCKS) - $(CONFIG_SYS_NAND_BBT_BLOCKS) \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE)`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BBT_SIZE=$(shell printf "%uk" `expr $(CONFIG_SYS_NAND_BBT_BLOCKS) \* $(CONFIG_SYS_NAND_BLOCK_SIZE) / 1024`)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_NAND_BBT_OFFSET=$(shell printf "0x%x" `expr \( $(CONFIG_SYS_NAND_BLOCKS) - $(CONFIG_SYS_NAND_BBT_BLOCKS) \) \* $(CONFIG_SYS_NAND_BLOCK_SIZE)`)
+endif # CONFIG_SYS_NAND_BLOCK_SIZE
+else
+ifneq ($(CONFIG_MMC_BOOT_SIZE),)
+       CONFIG_SYS_MMC_BOOT_PART_SIZE := $(shell expr $(CONFIG_MMC_BOOT_SIZE) \* 1024)
+else
+       CONFIG_SYS_MMC_BOOT_PART_SIZE := $(shell expr 4096 \* 1024)
+endif
+CONFIG_U_BOOT_IMG_SIZE := $(shell expr 1 \* 1048576)
+CONFIG_MAX_DTB_SIZE := $(shell expr 64 \* 1024)
+CONFIG_ENV_SIZE := $(shell expr 128 \* 1024)
+CONFIG_ENV_OFFSET := $(shell expr $(CONFIG_SYS_MMC_BOOT_PART_SIZE) - $(CONFIG_ENV_SIZE))
+CONFIG_SYS_DTB_OFFSET := $(shell expr $(CONFIG_ENV_OFFSET) - $(CONFIG_MAX_DTB_SIZE))
+
+PLATFORM_CPPFLAGS += -DCONFIG_ENV_SIZE=$(CONFIG_ENV_SIZE)
+PLATFORM_CPPFLAGS += -DCONFIG_U_BOOT_IMG_SIZE=$(CONFIG_U_BOOT_IMG_SIZE)
+PLATFORM_CPPFLAGS += -DCONFIG_MAX_DTB_SIZE=$(CONFIG_MAX_DTB_SIZE)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_DTB_PART_SIZE=$(CONFIG_MAX_DTB_SIZE)
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_MMC_BOOT_PART_SIZE=$(CONFIG_SYS_MMC_BOOT_PART_SIZE)
+PLATFORM_CPPFLAGS += -DCONFIG_ENV_OFFSET=$(shell printf "0x%x" $(CONFIG_ENV_OFFSET))
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_DTB_OFFSET=$(shell printf "0x%x" $(CONFIG_SYS_DTB_OFFSET))
+PLATFORM_CPPFLAGS += -DCONFIG_SYS_DTB_BLKNO=$(shell printf "0x%x" `expr $(CONFIG_SYS_DTB_OFFSET) / 512`)
+endif # CONFIG_TX6_NAND
diff --git a/board/karo/tx6/flash.c b/board/karo/tx6/flash.c
new file mode 100644 (file)
index 0000000..d0bb7c8
--- /dev/null
@@ -0,0 +1,739 @@
+/*
+ * Copyright (C) 2012-2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <nand.h>
+#include <errno.h>
+
+#include <linux/err.h>
+#include <jffs2/load_kernel.h>
+
+#include <asm/io.h>
+#include <linux/sizes.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/imx-common/regs-gpmi.h>
+#include <asm/imx-common/regs-bch.h>
+
+struct mx6_nand_timing {
+       u8 data_setup;
+       u8 data_hold;
+       u8 address_setup;
+       u8 dsample_time;
+       u8 nand_timing_state;
+       u8 tREA;
+       u8 tRLOH;
+       u8 tRHOH;
+};
+
+struct mx6_fcb {
+       u32 checksum;
+       u32 fingerprint;
+       u32 version;
+       struct mx6_nand_timing timing;
+       u32 page_data_size;
+       u32 total_page_size;
+       u32 sectors_per_block;
+       u32 number_of_nands;    /* not used by ROM code */
+       u32 total_internal_die; /* not used by ROM code */
+       u32 cell_type;          /* not used by ROM code */
+       u32 ecc_blockn_type;
+       u32 ecc_block0_size;
+       u32 ecc_blockn_size;
+       u32 ecc_block0_type;
+       u32 metadata_size;
+       u32 ecc_blocks_per_page;
+       u32 rsrvd1[6];          /* not used by ROM code */
+       u32 bch_mode;           /* erase_threshold */
+       u32 rsrvd2[2];
+       u32 fw1_start_page;
+       u32 fw2_start_page;
+       u32 fw1_sectors;
+       u32 fw2_sectors;
+       u32 dbbt_search_area;
+       u32 bb_mark_byte;
+       u32 bb_mark_startbit;
+       u32 bb_mark_phys_offset;
+       u32 bch_type;
+       u32 rsrvd3[8]; /* Toggle NAND timing parameters */
+       u32 disbbm;
+       u32 bb_mark_spare_offset;
+       u32 rsrvd4[9]; /* ONFI NAND parameters */
+       u32 disbb_search;
+};
+
+struct mx6_dbbt_header {
+       u32 checksum;
+       u32 fingerprint;
+       u32 version;
+       u32 number_bb;
+       u32 number_pages;
+       u8 spare[492];
+};
+
+struct mx6_dbbt {
+       u32 nand_number;
+       u32 number_bb;
+       u32 bb_num[2040 / 4];
+};
+
+#define BF_VAL(v, bf)          (((v) & bf##_MASK) >> bf##_OFFSET)
+
+static nand_info_t *mtd = &nand_info[0];
+
+extern void *_start;
+
+#define BIT(v,n)       (((v) >> (n)) & 0x1)
+
+static u8 calculate_parity_13_8(u8 d)
+{
+       u8 p = 0;
+
+       p |= (BIT(d, 6) ^ BIT(d, 5) ^ BIT(d, 3) ^ BIT(d, 2))             << 0;
+       p |= (BIT(d, 7) ^ BIT(d, 5) ^ BIT(d, 4) ^ BIT(d, 2) ^ BIT(d, 1)) << 1;
+       p |= (BIT(d, 7) ^ BIT(d, 6) ^ BIT(d, 5) ^ BIT(d, 1) ^ BIT(d, 0)) << 2;
+       p |= (BIT(d, 7) ^ BIT(d, 4) ^ BIT(d, 3) ^ BIT(d, 0))             << 3;
+       p |= (BIT(d, 6) ^ BIT(d, 4) ^ BIT(d, 3) ^ BIT(d, 2) ^ BIT(d, 1) ^ BIT(d, 0)) << 4;
+       return p;
+}
+
+static void encode_hamming_13_8(void *_src, void *_ecc, size_t size)
+{
+       int i;
+       u8 *src = _src;
+       u8 *ecc = _ecc;
+
+       for (i = 0; i < size; i++)
+               ecc[i] = calculate_parity_13_8(src[i]);
+}
+
+static u32 calc_chksum(void *buf, size_t size)
+{
+       u32 chksum = 0;
+       u8 *bp = buf;
+       size_t i;
+
+       for (i = 0; i < size; i++) {
+               chksum += bp[i];
+       }
+       return ~chksum;
+}
+
+/*
+  Physical organisation of data in NAND flash:
+  metadata
+  payload chunk 0 (may be empty)
+  ecc for metadata + payload chunk 0
+  payload chunk 1
+  ecc for payload chunk 1
+...
+  payload chunk n
+  ecc for payload chunk n
+ */
+
+static inline int calc_bb_offset(nand_info_t *mtd, struct mx6_fcb *fcb)
+{
+       int bb_mark_offset;
+       int chunk_data_size = fcb->ecc_blockn_size * 8;
+       int chunk_ecc_size = (fcb->ecc_blockn_type << 1) * 13;
+       int chunk_total_size = chunk_data_size + chunk_ecc_size;
+       int bb_mark_chunk, bb_mark_chunk_offs;
+
+       bb_mark_offset = (mtd->writesize - fcb->metadata_size) * 8;
+       if (fcb->ecc_block0_size == 0)
+               bb_mark_offset -= (fcb->ecc_block0_type << 1) * 13;
+
+       bb_mark_chunk = bb_mark_offset / chunk_total_size;
+       bb_mark_chunk_offs = bb_mark_offset - (bb_mark_chunk * chunk_total_size);
+       if (bb_mark_chunk_offs > chunk_data_size) {
+               printf("Unsupported ECC layout; BB mark resides in ECC data: %u\n",
+                       bb_mark_chunk_offs);
+               return -EINVAL;
+       }
+       bb_mark_offset -= bb_mark_chunk * chunk_ecc_size;
+       return bb_mark_offset;
+}
+
+/*
+ * return number of blocks to skip for a contiguous partition
+ * of given # blocks
+ */
+static int find_contig_space(int block, int num_blocks, int max_blocks)
+{
+       int skip = 0;
+       int found = 0;
+       int last = block + max_blocks;
+
+       debug("Searching %u contiguous blocks from %d..%d\n",
+               num_blocks, block, block + max_blocks - 1);
+       for (; block < last; block++) {
+               if (nand_block_isbad(mtd, block * mtd->erasesize)) {
+                       skip += found + 1;
+                       found = 0;
+                       debug("Skipping %u blocks to %u\n",
+                               skip, block + 1);
+               } else {
+                       found++;
+                       if (found >= num_blocks) {
+                               debug("Found %u good blocks from %d..%d\n",
+                                       found, block - found + 1, block);
+                               return skip;
+                       }
+               }
+       }
+       return -ENOSPC;
+}
+
+#define pr_fcb_val(p, n)       debug("%s=%08x(%d)\n", #n, (p)->n, (p)->n)
+
+static struct mx6_fcb *create_fcb(void *buf, int fw1_start_block,
+                               int fw2_start_block, int fw_num_blocks)
+{
+       struct gpmi_regs *gpmi_base = (void *)GPMI_BASE_ADDRESS;
+       struct bch_regs *bch_base = (void *)BCH_BASE_ADDRESS;
+       u32 fl0, fl1;
+       u32 t0;
+       int metadata_size;
+       int bb_mark_bit_offs;
+       struct mx6_fcb *fcb;
+       int fcb_offs;
+
+       if (gpmi_base == NULL || bch_base == NULL) {
+               return ERR_PTR(-ENOMEM);
+       }
+
+       fl0 = readl(&bch_base->hw_bch_flash0layout0);
+       fl1 = readl(&bch_base->hw_bch_flash0layout1);
+       t0 = readl(&gpmi_base->hw_gpmi_timing0);
+
+       metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+
+       fcb = buf + ALIGN(metadata_size, 4);
+       fcb_offs = (void *)fcb - buf;
+
+       memset(buf, 0xff, fcb_offs);
+       memset(fcb, 0x00, sizeof(*fcb));
+       memset(fcb + 1, 0xff, mtd->erasesize - fcb_offs - sizeof(*fcb));
+
+       strncpy((char *)&fcb->fingerprint, "FCB ", 4);
+       fcb->version = cpu_to_be32(1);
+
+       fcb->disbb_search = 0;
+       fcb->disbbm = 1;
+
+       /* ROM code assumes GPMI clock of 25 MHz */
+       fcb->timing.data_setup = BF_VAL(t0, GPMI_TIMING0_DATA_SETUP) * 40;
+       fcb->timing.data_hold = BF_VAL(t0, GPMI_TIMING0_DATA_HOLD) * 40;
+       fcb->timing.address_setup = BF_VAL(t0, GPMI_TIMING0_ADDRESS_SETUP) * 40;
+
+       fcb->page_data_size = mtd->writesize;
+       fcb->total_page_size = mtd->writesize + mtd->oobsize;
+       fcb->sectors_per_block = mtd->erasesize / mtd->writesize;
+
+       fcb->ecc_block0_type = BF_VAL(fl0, BCH_FLASHLAYOUT0_ECC0);
+       fcb->ecc_block0_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_DATA0_SIZE) * 4;
+       fcb->ecc_blockn_type = BF_VAL(fl1, BCH_FLASHLAYOUT1_ECCN);
+       fcb->ecc_blockn_size = BF_VAL(fl1, BCH_FLASHLAYOUT1_DATAN_SIZE) * 4;
+
+       pr_fcb_val(fcb, ecc_block0_type);
+       pr_fcb_val(fcb, ecc_blockn_type);
+       pr_fcb_val(fcb, ecc_block0_size);
+       pr_fcb_val(fcb, ecc_blockn_size);
+
+       fcb->metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
+       fcb->ecc_blocks_per_page = BF_VAL(fl0, BCH_FLASHLAYOUT0_NBLOCKS);
+       fcb->bch_mode = readl(&bch_base->hw_bch_mode);
+       fcb->bch_type = 0; /* BCH20 */
+
+       fcb->fw1_start_page = fw1_start_block * fcb->sectors_per_block;
+       fcb->fw1_sectors = fw_num_blocks * fcb->sectors_per_block;
+       pr_fcb_val(fcb, fw1_start_page);
+       pr_fcb_val(fcb, fw1_sectors);
+
+       if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
+               fcb->fw2_start_page = fw2_start_block * fcb->sectors_per_block;
+               fcb->fw2_sectors = fcb->fw1_sectors;
+               pr_fcb_val(fcb, fw2_start_page);
+               pr_fcb_val(fcb, fw2_sectors);
+       }
+
+       fcb->dbbt_search_area = 0;
+
+       bb_mark_bit_offs = calc_bb_offset(mtd, fcb);
+       if (bb_mark_bit_offs < 0)
+               return ERR_PTR(bb_mark_bit_offs);
+       fcb->bb_mark_byte = bb_mark_bit_offs / 8;
+       fcb->bb_mark_startbit = bb_mark_bit_offs % 8;
+       fcb->bb_mark_phys_offset = mtd->writesize;
+
+       pr_fcb_val(fcb, bb_mark_byte);
+       pr_fcb_val(fcb, bb_mark_startbit);
+       pr_fcb_val(fcb, bb_mark_phys_offset);
+
+       fcb->checksum = calc_chksum(&fcb->fingerprint, 512 - 4);
+       return fcb;
+}
+
+static int find_fcb(void *ref, int page)
+{
+       int ret = 0;
+       struct nand_chip *chip = mtd->priv;
+       void *buf = malloc(mtd->erasesize);
+
+       if (buf == NULL) {
+               return -ENOMEM;
+       }
+       chip->select_chip(mtd, 0);
+       chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
+       ret = chip->ecc.read_page_raw(mtd, chip, buf, 1, page);
+       if (ret) {
+               printf("Failed to read FCB from page %u: %d\n", page, ret);
+               goto out;
+       }
+       if (memcmp(buf, ref, mtd->writesize) == 0) {
+               debug("Found FCB in page %u (%08x)\n",
+                       page, page * mtd->writesize);
+               ret = 1;
+       }
+out:
+       chip->select_chip(mtd, -1);
+       free(buf);
+       return ret;
+}
+
+static int write_fcb(void *buf, int block)
+{
+       int ret;
+       struct nand_chip *chip = mtd->priv;
+       int page = block * mtd->erasesize / mtd->writesize;
+
+       ret = find_fcb(buf, page);
+       if (ret > 0) {
+               printf("FCB at block %d is up to date\n", block);
+               return 0;
+       }
+
+       ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
+       if (ret) {
+               printf("Failed to erase FCB block %u\n", block);
+               return ret;
+       }
+
+       printf("Writing FCB to block %d @ %08llx\n", block,
+               (u64)block * mtd->erasesize);
+       chip->select_chip(mtd, 0);
+       ret = chip->write_page(mtd, chip, 0, mtd->writesize,
+                       buf, 1, page, 0, 1);
+       if (ret) {
+               printf("Failed to write FCB to block %u: %d\n", block, ret);
+       }
+       chip->select_chip(mtd, -1);
+       return ret;
+}
+
+struct mx6_ivt {
+       u32 magic;
+       u32 entry;
+       u32 rsrvd1;
+       void *dcd;
+       void *boot_data;
+       void *self;
+       void *csf;
+       u32 rsrvd2;
+};
+
+struct mx6_boot_data {
+       u32 start;
+       u32 length;
+       u32 plugin;
+};
+
+static int find_ivt(void *buf)
+{
+       struct mx6_ivt *ivt_hdr = buf + 0x400;
+
+       if ((ivt_hdr->magic & 0xff0000ff) != 0x400000d1)
+               return 0;
+
+       return 1;
+}
+
+static inline void *reloc(void *dst, void *base, void *ptr)
+{
+       return dst + (ptr - base);
+}
+
+static int patch_ivt(void *buf, size_t fsize)
+{
+       struct mx6_ivt *ivt_hdr = buf + 0x400;
+       struct mx6_boot_data *boot_data;
+
+       if (!find_ivt(buf)) {
+               printf("No IVT found in image at %p\n", buf);
+               return -EINVAL;
+       }
+       boot_data = reloc(ivt_hdr, ivt_hdr->self, ivt_hdr->boot_data);
+       boot_data->length = fsize;
+
+       return 0;
+}
+
+#define chk_overlap(a,b)                               \
+       ((a##_start_block <= b##_end_block &&           \
+               a##_end_block >= b##_start_block) ||    \
+       (b##_start_block <= a##_end_block &&            \
+               b##_end_block >= a##_start_block))
+
+#define fail_if_overlap(a,b,m1,m2) do {                                \
+       if (chk_overlap(a, b)) {                                \
+               printf("%s blocks %lu..%lu overlap %s in blocks %lu..%lu!\n", \
+                       m1, a##_start_block, a##_end_block,     \
+                       m2, b##_start_block, b##_end_block);    \
+               return -EINVAL;                                 \
+       }                                                       \
+} while (0)
+
+static int tx6_prog_uboot(void *addr, int start_block, int skip,
+                       size_t size, size_t max_len)
+{
+       int ret;
+       nand_erase_options_t erase_opts = { 0, };
+       size_t actual;
+       size_t prg_length = max_len - skip * mtd->erasesize;
+       int prg_start = (start_block + skip) * mtd->erasesize;
+
+       erase_opts.offset = start_block * mtd->erasesize;
+       erase_opts.length = max_len;
+       erase_opts.quiet = 1;
+
+       printf("Erasing flash @ %08llx..%08llx\n", erase_opts.offset,
+               erase_opts.offset + erase_opts.length - 1);
+       ret = nand_erase_opts(mtd, &erase_opts);
+       if (ret) {
+               printf("Failed to erase flash: %d\n", ret);
+               return ret;
+       }
+
+       printf("Programming flash @ %08llx..%08llx from %p\n",
+               (u64)start_block * mtd->erasesize,
+               (u64)start_block * mtd->erasesize + size - 1, addr);
+       actual = size;
+       ret = nand_write_skip_bad(mtd, prg_start, &actual, NULL,
+                               prg_length, addr, WITH_DROP_FFS);
+       if (ret) {
+               printf("Failed to program flash: %d\n", ret);
+               return ret;
+       }
+       if (actual < size) {
+               printf("Could only write %u of %u bytes\n", actual, size);
+               return -EIO;
+       }
+       return 0;
+}
+
+#ifdef CONFIG_ENV_IS_IN_NAND
+#ifndef CONFIG_ENV_OFFSET_REDUND
+#define TOTAL_ENV_SIZE CONFIG_ENV_RANGE
+#else
+#define TOTAL_ENV_SIZE (CONFIG_ENV_RANGE * 2)
+#endif
+#endif
+
+int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int ret;
+       const unsigned long fcb_start_block = 0, fcb_end_block = 0;
+       int erase_size = mtd->erasesize;
+       int page_size = mtd->writesize;
+       void *buf;
+       char *load_addr;
+       char *file_size;
+       size_t size = 0;
+       void *addr = NULL;
+       struct mx6_fcb *fcb;
+       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+#ifdef CONFIG_ENV_IS_IN_NAND
+       unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
+       unsigned long env_end_block = env_start_block +
+               DIV_ROUND_UP(TOTAL_ENV_SIZE, mtd->erasesize) - 1;
+#endif
+       int optind;
+       int fw2_set = 0;
+       unsigned long fw1_start_block = 0, fw1_end_block;
+       unsigned long fw2_start_block = 0, fw2_end_block;
+       unsigned long fw_num_blocks;
+       int fw1_skip, fw2_skip;
+       unsigned long extra_blocks = 0;
+       size_t max_len1, max_len2;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       struct part_info *redund_part_info;
+       const char *uboot_part = "u-boot";
+       const char *redund_part = NULL;
+       u8 part_num;
+       u8 redund_part_num;
+
+       ret = mtdparts_init();
+       if (ret)
+               return ret;
+
+       for (optind = 1; optind < argc; optind++) {
+               char *endp;
+
+               if (strcmp(argv[optind], "-f") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       fw1_start_block = simple_strtoul(argv[optind], &endp, 0);
+                       if (*endp != '\0') {
+                               uboot_part = argv[optind];
+                               continue;
+                       }
+                       uboot_part = NULL;
+                       if (fw1_start_block >= mtd_num_blocks) {
+                               printf("Block number %lu is out of range: 0..%lu\n",
+                                       fw1_start_block, mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (strcmp(argv[optind], "-r") == 0) {
+                       fw2_set = 1;
+                       if (optind < argc - 1 && argv[optind + 1][0] != '-') {
+                               optind++;
+                               fw2_start_block = simple_strtoul(argv[optind],
+                                                               &endp, 0);
+                               if (*endp != '\0') {
+                                       redund_part = argv[optind];
+                                       continue;
+                               }
+                               if (fw2_start_block >= mtd_num_blocks) {
+                                       printf("Block number %lu is out of range: 0..%lu\n",
+                                               fw2_start_block,
+                                               mtd_num_blocks - 1);
+                                       return -EINVAL;
+                               }
+                       }
+               } else if (strcmp(argv[optind], "-e") == 0) {
+                       if (optind >= argc - 1) {
+                               printf("Option %s requires an argument\n",
+                                       argv[optind]);
+                               return -EINVAL;
+                       }
+                       optind++;
+                       extra_blocks = simple_strtoul(argv[optind], NULL, 0);
+                       if (extra_blocks >= mtd_num_blocks) {
+                               printf("Extra block count %lu is out of range: 0..%lu\n",
+                                       extra_blocks,
+                                       mtd_num_blocks - 1);
+                               return -EINVAL;
+                       }
+               } else if (argv[optind][0] == '-') {
+                       printf("Unrecognized option %s\n", argv[optind]);
+                       return -EINVAL;
+               } else {
+                       break;
+               }
+       }
+
+       load_addr = getenv("fileaddr");
+       file_size = getenv("filesize");
+
+       if (argc - optind < 1 && load_addr == NULL) {
+               printf("Load address not specified\n");
+               return -EINVAL;
+       }
+       if (argc - optind < 2 && file_size == NULL) {
+               printf("WARNING: Image size not specified; overwriting whole uboot partition\n");
+       }
+       if (argc > optind) {
+               load_addr = NULL;
+               addr = (void *)simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (argc > optind) {
+               file_size = NULL;
+               size = simple_strtoul(argv[optind], NULL, 16);
+               optind++;
+       }
+       if (load_addr != NULL) {
+               addr = (void *)simple_strtoul(load_addr, NULL, 16);
+               printf("Using default load address %p\n", addr);
+       }
+       if (file_size != NULL) {
+               size = simple_strtoul(file_size, NULL, 16);
+               printf("Using default file size %08x\n", size);
+       }
+       if (size > 0) {
+               fw_num_blocks = DIV_ROUND_UP(size, mtd->erasesize);
+       } else {
+               fw_num_blocks = part_info->size / mtd->erasesize -
+                       extra_blocks;
+               size = fw_num_blocks * mtd->erasesize;
+       }
+
+       if (uboot_part) {
+               ret = find_dev_and_part(uboot_part, &dev, &part_num,
+                                       &part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               uboot_part, ret);
+                       return ret;
+               }
+               fw1_start_block = part_info->offset / mtd->erasesize;
+               max_len1 = part_info->size;
+       } else {
+               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       }
+
+       if (redund_part) {
+               ret = find_dev_and_part(redund_part, &dev, &redund_part_num,
+                                       &redund_part_info);
+               if (ret) {
+                       printf("Failed to find '%s' partition: %d\n",
+                               redund_part, ret);
+                       return ret;
+               }
+               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               max_len2 = redund_part_info->size;
+       } else if (fw2_set) {
+               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+       } else {
+               max_len2 = 0;
+       }
+
+       fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
+                               max_len1 / mtd->erasesize);
+       if (fw1_skip < 0) {
+               printf("Could not find %lu contiguous good blocks for fw image\n",
+                       fw_num_blocks);
+               if (uboot_part) {
+#ifdef CONFIG_ENV_IS_IN_NAND
+                       if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
+                               printf("Use a different partition\n");
+                       } else {
+                               printf("Increase the size of the '%s' partition\n",
+                                       uboot_part);
+                       }
+#else
+                       printf("Increase the size of the '%s' partition\n",
+                               uboot_part);
+#endif
+               } else {
+                       printf("Increase the number of spare blocks to use with the '-e' option\n");
+               }
+               return -ENOSPC;
+       }
+       fw1_end_block = fw1_start_block + fw1_skip + fw_num_blocks - 1;
+
+       if (fw2_set && fw2_start_block == 0)
+               fw2_start_block = fw1_end_block + 1;
+       if (fw2_start_block > 0) {
+               fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
+                                       max_len2 / mtd->erasesize);
+               if (fw2_skip < 0) {
+                       printf("Could not find %lu contiguous good blocks for redundant fw image\n",
+                               fw_num_blocks);
+                       if (redund_part) {
+                               printf("Increase the size of the '%s' partition or use a different partition\n",
+                                       redund_part);
+                       } else {
+                               printf("Increase the number of spare blocks to use with the '-e' option\n");
+                       }
+                       return -ENOSPC;
+               }
+       } else {
+               fw2_skip = 0;
+       }
+       fw2_end_block = fw2_start_block + fw2_skip + fw_num_blocks - 1;
+
+#ifdef CONFIG_ENV_IS_IN_NAND
+       fail_if_overlap(fcb, env, "FCB", "Environment");
+       fail_if_overlap(fw1, env, "FW1", "Environment");
+#endif
+       fail_if_overlap(fcb, fw1, "FCB", "FW1");
+       if (fw2_set) {
+               fail_if_overlap(fcb, fw2, "FCB", "FW2");
+#ifdef CONFIG_ENV_IS_IN_NAND
+               fail_if_overlap(fw2, env, "FW2", "Environment");
+#endif
+               fail_if_overlap(fw1, fw2, "FW1", "FW2");
+       }
+
+       buf = malloc(erase_size);
+       if (buf == NULL) {
+               printf("Failed to allocate buffer\n");
+               return -ENOMEM;
+       }
+
+       fcb = create_fcb(buf, fw1_start_block + fw1_skip,
+                       fw2_start_block + fw2_skip, fw_num_blocks);
+       if (IS_ERR(fcb)) {
+               printf("Failed to initialize FCB: %ld\n", PTR_ERR(fcb));
+               free(buf);
+               return PTR_ERR(fcb);
+       }
+       encode_hamming_13_8(fcb, (void *)fcb + 512, 512);
+
+       ret = write_fcb(buf, fcb_start_block);
+       free(buf);
+       if (ret) {
+               printf("Failed to write FCB to block %lu\n", fcb_start_block);
+               return ret;
+       }
+       ret = patch_ivt(addr, size);
+       if (ret) {
+               return ret;
+       }
+
+       if (size & (page_size - 1)) {
+               memset(addr + size, 0xff, size & (page_size - 1));
+               size = ALIGN(size, page_size);
+       }
+
+       printf("Programming U-Boot image from %p to block %lu @ %08llx\n",
+               addr, fw1_start_block + fw1_skip,
+               (u64)(fw1_start_block + fw1_skip) * mtd->erasesize);
+       ret = tx6_prog_uboot(addr, fw1_start_block, fw1_skip, size,
+                       max_len1);
+
+       if (fw2_start_block == 0) {
+               return ret;
+       }
+
+       printf("Programming redundant U-Boot image to block %lu @ %08llx\n",
+               fw2_start_block + fw2_skip,
+               (u64)(fw2_start_block + fw2_skip) * mtd->erasesize);
+       ret = tx6_prog_uboot(addr, fw2_start_block, fw2_skip, fw_num_blocks,
+                       max_len2);
+       return ret;
+}
+
+U_BOOT_CMD(romupdate, 11, 0, do_update,
+       "Creates an FCB data structure and writes an U-Boot image to flash",
+       "[-f {<part>|block#}] [-r [{<part>|block#}]] [-e #] [<address>] [<length>]\n"
+       "\t-f <part>\twrite bootloader image to partition <part>\n"
+       "\t-f #\twrite bootloader image at block # (decimal)\n"
+       "\t-r\twrite redundant bootloader image at next free block after first image\n"
+       "\t-r <part>\twrite redundant bootloader image to partition <part>\n"
+       "\t-r #\twrite redundant bootloader image at block # (decimal)\n"
+       "\t-e #\tspecify number of redundant blocks per boot loader image\n"
+       "\t\tonly valid if -f or -r specify a flash address rather than a partition name\n"
+       "\t<address>\tRAM address of bootloader image (default: ${fileaddr}\n"
+       "\t<length>\tlength of bootloader image in RAM (default: ${filesize}"
+       );
diff --git a/board/karo/tx6/lowlevel_init.S b/board/karo/tx6/lowlevel_init.S
new file mode 100644 (file)
index 0000000..3161c22
--- /dev/null
@@ -0,0 +1,974 @@
+#include <config.h>
+#include <configs/tx6.h>
+#include <asm/arch/imx-regs.h>
+#include <generated/asm-offsets.h>
+
+#ifndef CCM_CCR
+#error asm-offsets not included
+#endif
+
+#define DEBUG_LED_BIT          20
+#define LED_GPIO_BASE          GPIO2_BASE_ADDR
+#define LED_MUX_OFFSET         0x0ec
+#define LED_MUX_MODE           0x15
+
+#define SDRAM_CLK              CONFIG_SYS_SDRAM_CLK
+
+#ifdef PHYS_SDRAM_2_SIZE
+#define SDRAM_SIZE             (PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE)
+#else
+#define SDRAM_SIZE             PHYS_SDRAM_1_SIZE
+#endif
+
+#define CPU_2_BE_32(l)                 \
+       ((((l) << 24) & 0xFF000000) |   \
+       (((l) << 8) & 0x00FF0000) |     \
+       (((l) >> 8) & 0x0000FF00) |     \
+       (((l) >> 24) & 0x000000FF))
+
+#define CHECK_DCD_ADDR(a)      (                       \
+       ((a) >= 0x020E0000 && (a) <= 0x020E3FFF) /* IOMUXC */ ||        \
+       ((a) >= 0x020C4000 && (a) <= 0x020C7FFF) /* CCM */ ||   \
+       ((a) >= 0x020C8000 && (a) <= 0x020C8FFF) /* ANALOG */ ||        \
+       ((a) >= 0x021B0000 && (a) <= 0x021B7FFF) /* MMDC */ ||  \
+       ((a) >= 0x00907000 && (a) <= 0x00937FF0) /* OCRAM */ || \
+       ((a) >= 0x08000000 && (a) <= 0x0FFEFFFF) /* EIM (CS0) */ ||     \
+       ((a) >= 0x10000000 && (a) <= 0xFFFFFFFF) /* SDRAM */)
+
+       .macro  mxc_dcd_item    addr, val
+       .ifne   CHECK_DCD_ADDR(\addr)
+       .word   CPU_2_BE_32(\addr), CPU_2_BE_32(\val)
+       .else
+       .error  "Address \addr not accessible from DCD"
+       .endif
+       .endm
+
+#define MXC_DCD_ITEM(addr, val)                mxc_dcd_item    (addr), (val)
+#if PHYS_SDRAM_1_WIDTH == 16
+#define MXC_DCD_ITEM_16(addr, val)             mxc_dcd_item    (addr), (val)
+#define MXC_DCD_CMD_CHK_16(type, flags, addr, mask) MXC_DCD_CMD_CHK(type, flags, addr, mask)
+#else
+#define MXC_DCD_ITEM_16(addr, val)
+#define MXC_DCD_CMD_CHK_16(type, flags, addr, mask)
+#endif
+#if PHYS_SDRAM_1_WIDTH > 16
+#define MXC_DCD_ITEM_32(addr, val)             mxc_dcd_item    (addr), (val)
+#define MXC_DCD_CMD_CHK_32(type, flags, addr, mask) MXC_DCD_CMD_CHK(type, flags, addr, mask)
+#else
+#define MXC_DCD_ITEM_32(addr, val)
+#define MXC_DCD_CMD_CHK_32(type, flags, addr, mask)
+#endif
+#if PHYS_SDRAM_1_WIDTH == 64
+#define MXC_DCD_ITEM_64(addr, val)             mxc_dcd_item    (addr), (val)
+#define MXC_DCD_CMD_CHK_64(type, flags, addr, mask) MXC_DCD_CMD_CHK(type, flags, addr, mask)
+#else
+#define MXC_DCD_ITEM_64(addr, val)
+#define MXC_DCD_CMD_CHK_64(type, flags, addr, mask)
+#endif
+
+#define MXC_DCD_CMD_SZ_BYTE            1
+#define MXC_DCD_CMD_SZ_SHORT           2
+#define MXC_DCD_CMD_SZ_WORD            4
+#define MXC_DCD_CMD_FLAG_WRITE         0x0
+#define MXC_DCD_CMD_FLAG_CLR           0x1
+#define MXC_DCD_CMD_FLAG_SET           0x3
+#define MXC_DCD_CMD_FLAG_CHK_CLR       ((0 << 0) | (0 << 1))
+#define MXC_DCD_CMD_FLAG_CHK_SET       ((0 << 0) | (1 << 1))
+#define MXC_DCD_CMD_FLAG_CHK_ANY_CLR   ((1 << 0) | (0 << 1))
+#define MXC_DCD_CMD_FLAG_CHK_ANY_SET   ((1 << 0) | (1 << 1))
+
+#define MXC_DCD_START                                                  \
+       .word   CPU_2_BE_32((0xd2 << 24) | ((dcd_end - .) << 8) | DCD_VERSION) ; \
+dcd_start:
+
+       .macro  MXC_DCD_END
+1:
+       .ifgt   . - dcd_start - 1768
+       .error  "DCD too large!"
+       .endif
+dcd_end:
+       .endm
+
+#define MXC_DCD_CMD_WRT(type, flags)                                   \
+1:     .word   CPU_2_BE_32((0xcc << 24) | ((1f - .) << 8) | ((flags) << 3) | (type))
+
+#define MXC_DCD_CMD_CHK(type, flags, addr, mask)                       \
+1:     .word   CPU_2_BE_32((0xcf << 24) | (12 << 8) | ((flags) << 3) | (type)), \
+               CPU_2_BE_32(addr), CPU_2_BE_32(mask)
+
+#define MXC_DCD_CMD_CHK_CNT(type, flags, addr, mask, count)            \
+1:     .word   CPU_2_BE_32((0xcf << 24) | (16 << 8) | ((flags) << 3) | (type)), \
+               CPU_2_BE_32(addr), CPU_2_BE_32(mask), CPU_2_BE_32(count)
+
+#define MXC_DCD_CMD_NOP()                              \
+1:     .word   CPU_2_BE_32((0xc0 << 24) | (4 << 8))
+
+
+#define CK_TO_NS(ck)   (((ck) * 1000 + SDRAM_CLK / 2) / SDRAM_CLK)
+#define NS_TO_CK(ns)   (((ns) * SDRAM_CLK + 999) / 1000)
+#define NS_TO_CK10(ns) DIV_ROUND_UP(NS_TO_CK(ns), 10)
+
+       .macro          CK_VAL, name, clks, offs, max
+       .iflt           \clks - \offs
+       .set            \name, 0
+       .else
+       .ifle           \clks - \offs - \max
+       .set            \name, \clks - \offs
+       .else
+       .error          "Value \clks out of range for parameter \name"
+       .endif
+       .endif
+       .endm
+
+       .macro          NS_VAL, name, ns, offs, max
+       .iflt           \ns - \offs
+       .set            \name, 0
+       .else
+       CK_VAL          \name, NS_TO_CK(\ns), \offs, \max
+       .endif
+       .endm
+
+       .macro          CK_MAX, name, ck1, ck2, offs, max
+       .ifgt           \ck1 - \ck2
+       CK_VAL          \name, \ck1, \offs, \max
+       .else
+       CK_VAL          \name, \ck2, \offs, \max
+       .endif
+       .endm
+
+#define MDMISC_DDR_TYPE_DDR3           0
+#define MDMISC_DDR_TYPE_LPDDR2         1
+#define MDMISC_DDR_TYPE_DDR2           2
+
+#define DIV_ROUND_UP(m,d)              (((m) + (d) - 1) / (d))
+
+#define MDOR_CLK_PERIOD_ns             15258   /* base clock for MDOR values */
+
+/* DDR3 SDRAM */
+#if SDRAM_SIZE > PHYS_SDRAM_1_SIZE
+#define BANK_ADDR_BITS                 2
+#else
+#define BANK_ADDR_BITS                 1
+#endif
+#define SDRAM_BURST_LENGTH             8
+#define RALAT                          5
+#define WALAT                          0
+#define BI_ON                          0
+#define ADDR_MIRROR                    0
+#define DDR_TYPE                       MDMISC_DDR_TYPE_DDR3
+
+/* 512/1024MiB SDRAM: NT5CB128M16FP-DII */
+#if SDRAM_CLK > 666 && SDRAM_CLK <= 800
+#define CL_VAL 11
+#define CWL_VAL        8
+#elif SDRAM_CLK > 533 && SDRAM_CLK <= 666
+#define CL_VAL 9 // or 10
+#define CWL_VAL        7
+#elif SDRAM_CLK > 400 && SDRAM_CLK <= 533
+#define CL_VAL 7 // or 8
+#define CWL_VAL        6
+#elif SDRAM_CLK > 333 && SDRAM_CLK <= 400
+#define CL_VAL 6
+#define CWL_VAL        5
+#elif SDRAM_CLK >= 303 && SDRAM_CLK <= 333
+#define CL_VAL 5
+#define CWL_VAL        5
+#else
+#error SDRAM clock out of range: 303 .. 800
+#endif
+
+/* MDCFG0 0x0c */
+NS_VAL tRFC,   160, 1, 255             /* clks - 1 (0..255) */
+CK_MAX tXS,    NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) tRFC + 10 */
+CK_MAX tXP,    NS_TO_CK10(75), 3, 1, 7 /* clks - 1 (0..7) */ /* max(3tCK, 7.5ns) */
+CK_MAX tXPDLL, NS_TO_CK(24), 2, 1, 15  /* clks - 1 (0..15) */
+NS_VAL tFAW,   50, 1, 31               /* clks - 1 (0..31) */
+CK_VAL tCL,    CL_VAL, 3, 8            /* clks - 3 (0..8) CAS Latency */
+
+/* MDCFG1 0x10 */
+CK_VAL tRCD,   NS_TO_CK10(125), 1, 7   /* clks - 1 (0..7) */ /* 12.5 */
+CK_VAL tRP,    NS_TO_CK10(125), 1, 7   /* clks - 1 (0..7) */ /* 12.5 */
+NS_VAL tRC,    50, 1, 31               /* clks - 1 (0..31) */
+CK_VAL tRAS,   NS_TO_CK10(375), 1, 31  /* clks - 1 (0..31) */ /* 37.5 */
+CK_VAL tRPA,   1, 0, 1                 /* clks     (0..1) */
+NS_VAL tWR,    15, 1, 15               /* clks - 1 (0..15) */
+CK_VAL tMRD,   4, 1, 15                /* clks - 1 (0..15) */
+CK_VAL tCWL,   CWL_VAL, 2, 6           /* clks - 2 (0..6) */
+
+/* MDCFG2 0x14 */
+CK_VAL tDLLK,  512, 1, 511             /* clks - 1 (0..511) */
+CK_MAX tRTP,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+CK_MAX tWTR,   NS_TO_CK10(75), 4, 1, 7 /* clks - 1 (0..7) */ /* max(4tCK, 7.5ns) */
+CK_MAX tRRD,   NS_TO_CK(10), 4, 1, 7   /* clks - 1 (0..7) */
+
+/* MDOR 0x30 */
+CK_MAX tXPR,   NS_TO_CK(CK_TO_NS(tRFC + 1) + 10), 5, 1, 255 /* clks - 1 (0..255) max(tRFC + 10, 5CK) */
+#define tSDE_RST       (DIV_ROUND_UP(200000, MDOR_CLK_PERIOD_ns) + 2)
+#define tRST_CKE       (DIV_ROUND_UP(500000, MDOR_CLK_PERIOD_ns) + 2)
+
+/* MDOTC 0x08 */
+CK_VAL tAOFPD, NS_TO_CK10(85), 1, 7    /* clks - 1 (0..7) */ /* 8.5ns */
+CK_VAL tAONPD, NS_TO_CK10(85), 1, 7    /* clks - 1 (0..7) */ /* 8.5ns */
+CK_VAL tANPD,  tCWL + 1, 1, 15         /* clks - 1 (0..15) */
+CK_VAL tAXPD,  tCWL + 1, 1, 15         /* clks - 1 (0..15) */
+CK_VAL tODTLon tCWL, 0, 7              /* clks - 1 (0..7) */ /* CWL+AL-2 */
+CK_VAL tODTLoff tCWL, 0, 31            /* clks - 1 (0..31) */ /* CWL+AL-2 */
+
+/* MDPDC 0x04 */
+CK_MAX tCKE,   NS_TO_CK(5), 3, 1, 7
+CK_MAX tCKSRX, NS_TO_CK(10), 5, 0, 7
+CK_MAX tCKSRE, NS_TO_CK(10), 5, 0, 7
+
+#define PRCT           0
+#define PWDT           5
+#define SLOW_PD                0
+#define BOTH_CS_PD     1
+
+#define MDPDC_VAL_0    (       \
+       (PRCT << 28) |          \
+       (PRCT << 24) |          \
+       (tCKE << 16) |          \
+       (SLOW_PD << 7) |        \
+       (BOTH_CS_PD << 6) |     \
+       (tCKSRX << 3) |         \
+       (tCKSRE << 0)           \
+       )
+
+#define MDPDC_VAL_1    (MDPDC_VAL_0 |          \
+       (PWDT << 12) |                          \
+       (PWDT << 8)                             \
+       )
+
+#define ROW_ADDR_BITS                  14
+#define COL_ADDR_BITS                  10
+
+#define Rtt_Nom                                1 /* ODT: 0: off 1: RZQ/4 2: RZQ/2 3: RZQ/6 4: RZQ/12 5: RZQ/8 */
+#define Rtt_WR                         0 /* Dynamic ODT: 0: off 1: RZQ/4 2: RZQ/2 */
+#define DLL_DISABLE                    0
+
+       .iflt   tWR - 7
+       .set    mr0_val, (((1 - DLL_DISABLE) << 8) /* DLL Reset */ |    \
+                       (SLOW_PD << 12) /* PD exit: 0: fast 1: slow */ |\
+                       ((tWR + 1 - 4) << 9) |                          \
+                       ((((tCL + 3) - 4) & 0x7) << 4) |                \
+                       ((((tCL + 3) - 4) & 0x8) >> 1))
+       .else
+       .set    mr0_val, ((1 << 8) /* DLL Reset */ |                    \
+                       (SLOW_PD << 12) /* PD exit: 0: fast 1: slow */ |\
+                       (((tWR + 1) / 2) << 9) |        \
+                       ((((tCL + 3) - 4) & 0x7) << 4) | \
+                       ((((tCL + 3) - 4) & 0x8) >> 1))
+       .endif
+
+#define mr1_val                                (                                       \
+                                        ((Rtt_Nom & 1) << 2) |                 \
+                                        (((Rtt_Nom >> 1) & 1) << 6) |          \
+                                        (((Rtt_Nom >> 2) & 1) << 9) |          \
+                                        (DLL_DISABLE << 0) |                   \
+                                       0)
+#define mr2_val                                (                                       \
+                                        (Rtt_WR << 9) /* dynamic ODT */ |      \
+                                        (0 << 7) /* SRT: Ext. temp. (mutually exclusive with ASR!) */ | \
+                                        (1 << 6) | /* ASR: Automatic Self Refresh */ \
+                                        (((tCWL + 2) - 5) << 3) |              \
+                                       0)
+#define mr3_val                                0
+
+#define MDSCR_MRS_VAL(cs, mr, val)     (((val) << 16) |                \
+                                       (1 << 15) /* CON_REQ */ |       \
+                                       (3 << 4) /* MRS command */ |    \
+                                       ((cs) << 3) |                   \
+                                       ((mr) << 0) |                   \
+                                       0)
+
+#define MDCFG0_VAL     (       \
+       (tRFC << 24) |          \
+       (tXS << 16) |           \
+       (tXP << 13) |           \
+       (tXPDLL << 9) |         \
+       (tFAW << 4) |           \
+       (tCL << 0))             \
+
+#define MDCFG1_VAL     (       \
+       (tRCD << 29) |          \
+       (tRP << 26) |           \
+       (tRC << 21) |           \
+       (tRAS << 16) |          \
+       (tRPA << 15) |          \
+       (tWR << 9) |            \
+       (tMRD << 5) |           \
+       (tCWL << 0))            \
+
+#define MDCFG2_VAL     (       \
+       (tDLLK << 16) |         \
+       (tRTP << 6) |           \
+       (tWTR << 3) |           \
+       (tRRD << 0))
+
+#define BURST_LEN              (SDRAM_BURST_LENGTH / 8) /* 0: 4 byte 1: 8 byte */
+
+#define MDCTL_VAL              (((ROW_ADDR_BITS - 11) << 24) |         \
+                               ((COL_ADDR_BITS - 9) << 20) |           \
+                               (BURST_LEN << 19) |                     \
+                               ((PHYS_SDRAM_1_WIDTH / 32) << 16) |     \
+                               ((-1) << (32 - BANK_ADDR_BITS)))
+
+#define MDMISC_VAL             ((ADDR_MIRROR << 19) |  \
+                               (WALAT << 16) |         \
+                               (BI_ON << 12) |         \
+                               (0x3 << 9) |            \
+                               (RALAT << 6) |          \
+                               (DDR_TYPE << 3))
+
+#define MDOR_VAL               ((tXPR << 16) | (tSDE_RST << 8) | (tRST_CKE << 0))
+
+#define MDOTC_VAL              ((tAOFPD << 27) |       \
+                               (tAONPD << 24) |        \
+                               (tANPD << 20) |         \
+                               (tAXPD << 16) |         \
+                               (tODTLon << 12) |       \
+                               (tODTLoff << 4))
+
+ivt_header:
+       .word   CPU_2_BE_32((0xd1 << 24) | (32 << 8) | 0x40)
+app_start_addr:
+       .long   _start
+       .long   0x0
+dcd_ptr:
+       .long   dcd_hdr
+boot_data_ptr:
+       .word   boot_data
+self_ptr:
+       .word   ivt_header
+app_code_csf:
+       .word   0x0
+       .word   0x0
+boot_data:
+       .long   _start
+image_len:
+       .long   CONFIG_U_BOOT_IMG_SIZE
+plugin:
+       .word   0
+ivt_end:
+#define DCD_VERSION    0x40
+
+#define DDR_SEL_VAL    3 /* DDR3 */
+#if PHYS_SDRAM_1_WIDTH == 16
+#define DSE1_VAL       6 /* Drive Strength for DATA lines */
+#define DSE2_VAL       6 /* Drive Strength for ADDR/CMD lines */
+#else
+#define DSE1_VAL       6 /* Drive Strength for DATA lines */
+#define DSE2_VAL       6 /* Drive Strength for ADDR/CMD lines */
+#endif
+#define ODT_VAL                2
+#define DDR_PKE_VAL    0
+
+#define DDR_SEL_SHIFT  18
+#define DDR_MODE_SHIFT 17
+#define ODT_SHIFT      8
+#define DSE_SHIFT      3
+#define HYS_SHIFT      16
+#define PKE_SHIFT      12
+#define PUE_SHIFT      13
+#define PUS_SHIFT      14
+
+#define DDR_SEL_MASK   (DDR_SEL_VAL << DDR_SEL_SHIFT)
+#define DDR_MODE_MASK  (1 << DDR_MODE_SHIFT) /* differential input mode */
+#define DSE1_MASK      (DSE1_VAL << DSE_SHIFT)
+#define DSE2_MASK      (DSE2_VAL << DSE_SHIFT)
+#define ODT_MASK       (ODT_VAL << ODT_SHIFT)
+#define DDR_PKE_MASK   (DDR_PKE_VAL << PKE_SHIFT)
+
+#define DQM_MASK       (DDR_MODE_MASK | DSE2_MASK)
+#define SDQS_MASK      DSE2_MASK
+#define SDODT_MASK     (DSE2_MASK | (1 << PKE_SHIFT) | (1 << PUE_SHIFT) | (0 << PUS_SHIFT))
+#define SDCLK_MASK     (DDR_MODE_MASK | DSE2_MASK)
+#define SDCKE_MASK     ((1 << PKE_SHIFT) | (1 << PUE_SHIFT) | (0 << PUS_SHIFT))
+#define DDR_ADDR_MASK  (ODT_MASK | DDR_MODE_MASK)
+#define DDR_CTRL_MASK  (DDR_MODE_MASK | DSE2_MASK)
+
+#define MMDC1_MDCTL                            0x021b0000
+#define MMDC1_MDPDC                            0x021b0004
+#define MMDC1_MDOTC                            0x021b0008
+#define MMDC1_MDCFG0                           0x021b000c
+#define MMDC1_MDCFG1                           0x021b0010
+#define MMDC1_MDCFG2                           0x021b0014
+#define MMDC1_MDMISC                           0x021b0018
+#define MMDC1_MDSCR                            0x021b001c
+#define MMDC1_MDREF                            0x021b0020
+#define MMDC1_MDRWD                            0x021b002c
+#define MMDC1_MDOR                             0x021b0030
+#define MMDC1_MDASP                            0x021b0040
+#define MMDC1_MAPSR                            0x021b0404
+#define MMDC1_MPZQHWCTRL                       0x021b0800
+#define MMDC1_MPWLGCR                          0x021b0808
+#define MMDC1_MPWLDECTRL0                      0x021b080c
+#define MMDC1_MPWLDECTRL1                      0x021b0810
+#define MMDC1_MPWLDLST                         0x021b0814
+#define MMDC1_MPODTCTRL                                0x021b0818
+#define MMDC1_MPRDDQBY0DL                      0x021b081c
+#define MMDC1_MPRDDQBY1DL                      0x021b0820
+#define MMDC1_MPRDDQBY2DL                      0x021b0824
+#define MMDC1_MPRDDQBY3DL                      0x021b0828
+#define MMDC1_MPDGCTRL0                                0x021b083c
+#define MMDC1_MPDGCTRL1                                0x021b0840
+#define MMDC1_MPDGDLST0                                0x021b0844
+#define MMDC1_MPRDDLCTL                                0x021b0848
+#define MMDC1_MPRDDLST                         0x021b084c
+#define MMDC1_MPWRDLCTL                                0x021b0850
+#define MMDC1_MPWRDLST                         0x021b0854
+#define MMDC1_MPRDDLHWCTL                      0x021b0860
+#define MMDC1_MPWRDLHWCTL                      0x021b0864
+#define MMDC1_MPPDCMPR2                                0x021b0890
+#define MMDC1_MPSWDRDR0                                0x021b0898
+#define MMDC1_MPSWDRDR1                                0x021b089c
+#define MMDC1_MPSWDRDR2                                0x021b08a0
+#define MMDC1_MPSWDRDR3                                0x021b08a4
+#define MMDC1_MPSWDRDR4                                0x021b08a8
+#define MMDC1_MPSWDRDR5                                0x021b08ac
+#define MMDC1_MPSWDRDR6                                0x021b08b0
+#define MMDC1_MPSWDRDR7                                0x021b08b4
+#define MMDC1_MPMUR0                           0x021b08b8
+
+#if PHYS_SDRAM_1_WIDTH == 64
+#define MMDC2_MDPDC                            0x021b4004
+#define MMDC2_MPWLGCR                          0x021b4808
+#define MMDC2_MPWLDECTRL0                      0x021b480c
+#define MMDC2_MPWLDECTRL1                      0x021b4810
+#define MMDC2_MPWLDLST                         0x021b4814
+#define MMDC2_MPODTCTRL                                0x021b4818
+#define MMDC2_MPRDDQBY0DL                      0x021b481c
+#define MMDC2_MPRDDQBY1DL                      0x021b4820
+#define MMDC2_MPRDDQBY2DL                      0x021b4824
+#define MMDC2_MPRDDQBY3DL                      0x021b4828
+#define MMDC2_MPDGCTRL0                                0x021b483c
+#define MMDC2_MPDGCTRL1                                0x021b4840
+#define MMDC2_MPDGDLST0                                0x021b4844
+#define MMDC2_MPRDDLCTL                                0x021b4848
+#define MMDC2_MPRDDLST                         0x021b484c
+#define MMDC2_MPWRDLCTL                                0x021b4850
+#define MMDC2_MPWRDLST                         0x021b4854
+#define MMDC2_MPRDDLHWCTL                      0x021b4860
+#define MMDC2_MPWRDLHWCTL                      0x021b4864
+#define MMDC2_MPRDDLHWST0                      0x021b4868
+#define MMDC2_MPRDDLHWST1                      0x021b486c
+#define MMDC2_MPWRDLHWST0                      0x021b4870
+#define MMDC2_MPWRDLHWST1                      0x021b4874
+#define MMDC2_MPWLHWERR                                0x021b4878
+#define MMDC2_MPDGHWST0                                0x021b487c
+#define MMDC2_MPDGHWST1                                0x021b4880
+#define MMDC2_MPDGHWST2                                0x021b4884
+#define MMDC2_MPDGHWST3                                0x021b4888
+#define MMDC2_MPSWDAR0                         0x021b4894
+#define MMDC2_MPSWDRDR0                                0x021b4898
+#define MMDC2_MPSWDRDR1                                0x021b489c
+#define MMDC2_MPSWDRDR2                                0x021b48a0
+#define MMDC2_MPSWDRDR3                                0x021b48a4
+#define MMDC2_MPSWDRDR4                                0x021b48a8
+#define MMDC2_MPSWDRDR5                                0x021b48ac
+#define MMDC2_MPSWDRDR6                                0x021b48b0
+#define MMDC2_MPSWDRDR7                                0x021b48b4
+#endif
+
+#ifdef CONFIG_MX6Q
+#define IOMUXC_GPR1                            0x020e0004
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO17           0x020e024c
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7                0x020e02a8
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6                0x020e02ac
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0                0x020e02c0
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1                0x020e02c4
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_CLE         0x020e02d4
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_ALE         0x020e02d8
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B                0x020e02dc
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_READY       0x020e02e0
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B       0x020e02e4
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_CS2_B       0x020e02ec
+#define IOMUXC_SW_MUX_CTL_PAD_SD4_CMD          0x020e02f4
+#define IOMUXC_SW_MUX_CTL_PAD_SD4_CLK          0x020e02f8
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA00      0x020e02fc
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA01      0x020e0300
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA02      0x020e0304
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA03      0x020e0308
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA04      0x020e030c
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05      0x020e0310
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06      0x020e0314
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07      0x020e0318
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P     0x020e050c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5                0x020e0510
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4                0x020e0514
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4_P     0x020e0518
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3_P     0x020e051c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3                0x020e0520
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2_P     0x020e0524
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2                0x020e0528
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR00      0x020e052c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR01      0x020e0530
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR02      0x020e0534
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR03      0x020e0538
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR04      0x020e053c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR05      0x020e0540
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR06      0x020e0544
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR07      0x020e0548
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR08      0x020e054c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR09      0x020e0550
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR10      0x020e0554
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR11      0x020e0558
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR12      0x020e055c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR13      0x020e0560
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR14      0x020e0564
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR15      0x020e0568
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS         0x020e056c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS         0x020e0578
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET       0x020e057c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA0       0x020e0580
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA1       0x020e0584
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK0_P    0x020e0588
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2       0x020e058c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE0      0x020e0590
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK1_P    0x020e0594
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE1      0x020e0598
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT0                0x020e059c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT1                0x020e05a0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0_P     0x020e05a8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0                0x020e05ac
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P     0x020e05b0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1                0x020e05b4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P     0x020e05b8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6                0x020e05bc
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P     0x020e05c0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7                0x020e05c4
+#define IOMUXC_SW_PAD_CTL_GRP_B7DS             0x020e0748
+#define IOMUXC_SW_PAD_CTL_GRP_ADDDS            0x020e074c
+#define IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL      0x020e0750
+#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL0                0x020e0754
+#define IOMUXC_SW_PAD_CTL_GRP_DDRPKE           0x020e0758
+#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL1                0x020e075c
+#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL2                0x020e0760
+#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL3                0x020e0764
+#define IOMUXC_SW_PAD_CTL_GRP_DDRPK            0x020e0768
+#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL4                0x020e076c
+#define IOMUXC_SW_PAD_CTL_GRP_DDRHYS           0x020e0770
+#define IOMUXC_SW_PAD_CTL_GRP_DDRMODE          0x020e0774
+#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL5                0x020e0778
+#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL6                0x020e077c
+#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL7                0x020e0780
+#define IOMUXC_SW_PAD_CTL_GRP_B0DS             0x020e0784
+#define IOMUXC_SW_PAD_CTL_GRP_B1DS             0x020e0788
+#define IOMUXC_SW_PAD_CTL_GRP_CTLDS            0x020e078c
+#define IOMUXC_SW_PAD_CTL_GRP_B2DS             0x020e0794
+#define IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE         0x020e0798
+#define IOMUXC_SW_PAD_CTL_GRP_B3DS             0x020e079c
+#define IOMUXC_SW_PAD_CTL_GRP_B4DS             0x020e07a0
+#define IOMUXC_SW_PAD_CTL_GRP_B5DS             0x020e07a4
+#define IOMUXC_SW_PAD_CTL_GRP_B6DS             0x020e07a8
+#define IOMUXC_UART1_UART_RTS_B_SELECT_INPUT   0x020e091c
+#define IOMUXC_UART1_UART_RX_DATA_SELECT_INPUT 0x020e0920
+#endif
+
+#if defined(CONFIG_MX6DL) || defined(CONFIG_MX6S)
+#define IOMUXC_GPR1                            0x020e0004
+#define IOMUXC_SW_MUX_CTL_PAD_GPIO17           0x020e0218
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7                0x020e0330
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6                0x020e032c
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0                0x020e0314
+#define IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1                0x020e0318
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_CLE         0x020e0270
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_ALE         0x020e026c
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B                0x020e02a8
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_READY       0x020e02a4
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B       0x020e0274
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_CS2_B       0x020e027c
+#define IOMUXC_SW_MUX_CTL_PAD_SD4_CMD          0x020e033c
+#define IOMUXC_SW_MUX_CTL_PAD_SD4_CLK          0x020e0338
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA00      0x020e0284
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA01      0x020e0288
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA02      0x020e028c
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA03      0x020e0290
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA04      0x020e0294
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05      0x020e0298
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06      0x020e029c
+#define IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07      0x020e02a0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P     0x020e04d0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5                0x020e0484
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4                0x020e0480
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4_P     0x020e04cc
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3_P     0x020e04c8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3                0x020e047c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2_P     0x020e04c4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2                0x020e0478
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR00      0x020e0424
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR01      0x020e0428
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR02      0x020e0444
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR03      0x020e0448
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR04      0x020e044c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR05      0x020e0450
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR06      0x020e0454
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR07      0x020e0458
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR08      0x020e045c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR09      0x020e0460
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR10      0x020e042c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR11      0x020e0430
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR12      0x020e0434
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR13      0x020e0438
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR14      0x020e043c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR15      0x020e0440
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS         0x020e0464
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS         0x020e0490
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET       0x020e0494
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA0       0x020e0498
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA1       0x020e049c
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK0_P    0x020e04ac
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2       0x020e04a0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE0      0x020e04a4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK1_P    0x020e04b0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE1      0x020e04a8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT0                0x020e04b4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT1                0x020e04b8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0_P     0x020e04bc
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0                0x020e0470
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P     0x020e04c0
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1                0x020e0474
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P     0x020e04d4
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6                0x020e0488
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P     0x020e04d8
+#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7                0x020e048c
+#define IOMUXC_SW_PAD_CTL_GRP_B7DS             0x020e0748
+#define IOMUXC_SW_PAD_CTL_GRP_ADDDS            0x020e074c
+#define IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL      0x020e0750
+#define IOMUXC_SW_PAD_CTL_GRP_DDRPKE           0x020e0754
+#define IOMUXC_SW_PAD_CTL_GRP_DDRPK            0x020e0758
+#define IOMUXC_SW_PAD_CTL_GRP_DDRHYS           0x020e075c
+#define IOMUXC_SW_PAD_CTL_GRP_DDRMODE          0x020e0760
+#define IOMUXC_SW_PAD_CTL_GRP_B0DS             0x020e0784
+#define IOMUXC_SW_PAD_CTL_GRP_B1DS             0x020e0788
+#define IOMUXC_SW_PAD_CTL_GRP_CTLDS            0x020e078c
+#define IOMUXC_SW_PAD_CTL_GRP_B2DS             0x020e0794
+#define IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE         0x020e0798
+#define IOMUXC_SW_PAD_CTL_GRP_B3DS             0x020e079c
+#define IOMUXC_SW_PAD_CTL_GRP_B4DS             0x020e07a0
+#define IOMUXC_SW_PAD_CTL_GRP_B5DS             0x020e07a4
+#define IOMUXC_SW_PAD_CTL_GRP_B6DS             0x020e07a8
+#define IOMUXC_UART1_UART_RTS_B_SELECT_INPUT   0x020e08f8
+#define IOMUXC_UART1_UART_RX_DATA_SELECT_INPUT 0x020e08fc
+#endif
+
+dcd_hdr:
+       MXC_DCD_START
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+       /* RESET_OUT GPIO_7_12 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_GPIO17, 0x00000005)
+
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CS2CDR, 0x006336c1) /* default: 0x007236c1 */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CHSCCDR, 0x00012093) /* default: 0x0002a150 */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CSCDR2, 0x00012090) /* default: 0x0002a150 */
+
+       MXC_DCD_ITEM(ANATOP_BASE_ADDR + ANATOP_PLL_ENET, 0x00002001) /* ENET PLL */
+
+       /* enable all relevant clocks... */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CCGR0, 0xf0c03f3f) /* default: 0xf0c03f0f APBH-DMA */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CCGR1, 0xf0fc0c00) /* default: 0xf0fc0000 */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CCGR2, 0xfc3ff0cc) /* default: 0xfc3ff00c I2C1 */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CCGR3, 0x3ff00000) /* default: 0x3ff00000 */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CCGR4, 0xff00ff00) /* default: 0x0000ff00 GPMI BCH */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CCGR5, 0xff033f0f) /* default: 0xf0033f0f UART1 */
+       MXC_DCD_ITEM(CCM_BASE_ADDR + CCM_CCGR6, 0xffff03ff) /* default: 0xffff0003 USDHC4 (for APBH-DMA!) USDHC3 (for BCH!) */
+       MXC_DCD_ITEM(0x020c80a0, 0x80082029) /* set video PLL to 984MHz */
+       MXC_DCD_ITEM(0x020c80b0, 0x00065b9a)
+       MXC_DCD_ITEM(0x020c80c0, 0x000f4240)
+
+       /* IOMUX: */
+       MXC_DCD_ITEM(IOMUXC_GPR1, 0x48640005) /* default: 0x48400005 ENET_CLK output */
+       /* UART1 pad config */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7,        0x00000001)        /* UART1 TXD */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6,        0x00000001)        /* UART1 RXD */
+#ifdef CONFIG_MX6Q
+       MXC_DCD_ITEM(IOMUXC_UART1_UART_RX_DATA_SELECT_INPUT, 0x00000003)        /* UART1 RXD INPUT_SEL */
+#else
+       MXC_DCD_ITEM(IOMUXC_UART1_UART_RX_DATA_SELECT_INPUT, 0x00000002)        /* UART1 RXD INPUT_SEL */
+#endif
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0,        0x00000001)        /* UART1 CTS */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1,        0x00000001)        /* UART1 RTS */
+       MXC_DCD_ITEM(IOMUXC_UART1_UART_RTS_B_SELECT_INPUT,   0x00000003)        /* UART1 RTS INPUT_SEL */
+
+#ifdef CONFIG_NAND_MXS
+       /* NAND */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_CLE,    0x00000000)     /* NANDF_CLE: NANDF_CLE */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_ALE,    0x00000000)     /* NANDF_ALE: NANDF_ALE */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B,   0x00000000)     /* NANDF_WP_B: NANDF_WPn */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_READY,  0x00000000)     /* NANDF_RB0: NANDF_READY0 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B,  0x00000000)     /* NANDF_CS0: NANDF_CS0 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD4_CMD,     0x00000001)     /* SD4_CMD: NANDF_RDn */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_SD4_CLK,     0x00000001)     /* SD4_CLK: NANDF_WRn */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA00, 0x00000000)     /* NANDF_D0: NANDF_D0 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA01, 0x00000000)     /* NANDF_D1: NANDF_D1 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA02, 0x00000000)     /* NANDF_D2: NANDF_D2 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA03, 0x00000000)     /* NANDF_D3: NANDF_D3 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA04, 0x00000000)     /* NANDF_D4: NANDF_D4 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05, 0x00000000)     /* NANDF_D5: NANDF_D5 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06, 0x00000000)     /* NANDF_D6: NANDF_D6 */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07, 0x00000000)     /* NANDF_D7: NANDF_D7 */
+#endif
+       /* ext. mem CS */
+       MXC_DCD_ITEM(IOMUXC_SW_MUX_CTL_PAD_NAND_CS2_B, 0x00000000)      /* NANDF_CS2: NANDF_CS2 */
+       /* DRAM_DQM[0..7] */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0, DQM_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1, DQM_MASK)
+       MXC_DCD_ITEM_32(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2, DQM_MASK)
+       MXC_DCD_ITEM_32(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3, DQM_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4, DQM_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5, DQM_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6, DQM_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7, DQM_MASK)
+
+       /* DRAM_A[0..15] */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR00, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR01, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR02, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR03, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR04, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR05, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR06, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR07, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR08, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR09, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR10, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR11, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR12, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR13, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR14, DDR_ADDR_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ADDR15, DDR_ADDR_MASK)
+       /* DRAM_CAS */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS, DDR_CTRL_MASK)
+       /* DRAM_RAS */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS, DDR_CTRL_MASK)
+       /* DRAM_SDCLK[0..1] */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK0_P, SDCLK_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK1_P, SDCLK_MASK)
+       /* DRAM_RESET */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET, DDR_CTRL_MASK)
+       /* DRAM_SDCKE[0..1] */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE0, SDCKE_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE1, SDCKE_MASK)
+       /* DRAM_SDBA[0..2] */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA0, 0x00000000)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA1, 0x00000000)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2, 0x00000000)
+       /* DRAM_SDODT[0..1] */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT0, SDODT_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_ODT1, SDODT_MASK)
+       /* DRAM_B[0..7]DS */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B0DS, DSE1_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_B1DS, DSE1_MASK)
+       MXC_DCD_ITEM_32(IOMUXC_SW_PAD_CTL_GRP_B2DS, DSE1_MASK)
+       MXC_DCD_ITEM_32(IOMUXC_SW_PAD_CTL_GRP_B3DS, DSE1_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_GRP_B4DS, DSE1_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_GRP_B5DS, DSE1_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_GRP_B6DS, DSE1_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_GRP_B7DS, DSE1_MASK)
+       /* ADDDS */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_ADDDS, DSE2_MASK)
+       /* DDRMODE_CTL */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL, DDR_MODE_MASK)
+       /* DDRPKE */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_DDRPKE, DDR_PKE_MASK)
+       /* DDRMODE */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_DDRMODE, DDR_MODE_MASK)
+       /* CTLDS */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_CTLDS, DSE2_MASK)
+       /* DDR_TYPE */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE, DDR_SEL_MASK)
+       /* DDRPK */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_DDRPK, 1 << PUE_SHIFT)
+       /* DDRHYS */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_DDRHYS, 0x00000000)
+
+#ifdef CONFIG_MX6Q
+       /* TERM_CTL[0..7] */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL0, ODT_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL1, ODT_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL2, ODT_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL3, ODT_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL4, ODT_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL5, ODT_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL6, ODT_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_GRP_TERM_CTL7, ODT_MASK)
+#endif
+       /* SDRAM initialization */
+       /* MPRDDQBY[0..7]DL */
+       MXC_DCD_ITEM(MMDC1_MPRDDQBY0DL, 0x33333333)
+       MXC_DCD_ITEM(MMDC1_MPRDDQBY1DL, 0x33333333)
+       MXC_DCD_ITEM_32(MMDC1_MPRDDQBY2DL, 0x33333333)
+       MXC_DCD_ITEM_32(MMDC1_MPRDDQBY3DL, 0x33333333)
+       MXC_DCD_ITEM_64(MMDC2_MPRDDQBY0DL, 0x33333333)
+       MXC_DCD_ITEM_64(MMDC2_MPRDDQBY1DL, 0x33333333)
+       MXC_DCD_ITEM_64(MMDC2_MPRDDQBY2DL, 0x33333333)
+       MXC_DCD_ITEM_64(MMDC2_MPRDDQBY3DL, 0x33333333)
+       /* MDMISC */
+       MXC_DCD_ITEM(MMDC1_MDMISC, MDMISC_VAL | 2) /* reset MMDC FSM */
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MDMISC, 0x00000002)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
+       /* MSDSCR Conf Req */
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x00008000)
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_SET, MMDC1_MDSCR, 0x00004000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
+       /* MDCTL */
+       MXC_DCD_ITEM(MMDC1_MDCTL, MDCTL_VAL)
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_SET, MMDC1_MDMISC, 0x40000000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
+       MXC_DCD_ITEM(MMDC1_MDCFG0, MDCFG0_VAL)
+       MXC_DCD_ITEM(MMDC1_MDCFG1, MDCFG1_VAL)
+       MXC_DCD_ITEM(MMDC1_MDCFG2, MDCFG2_VAL)
+       MXC_DCD_ITEM(MMDC1_MDRWD,  0x000026d2)
+       MXC_DCD_ITEM(MMDC1_MDOR,   MDOR_VAL)
+       MXC_DCD_ITEM(MMDC1_MDOTC,  MDOTC_VAL)
+       MXC_DCD_ITEM(MMDC1_MDPDC,  MDPDC_VAL_0)
+       MXC_DCD_ITEM_64(MMDC2_MDPDC,  MDPDC_VAL_0)
+       MXC_DCD_ITEM(MMDC1_MDASP,  (PHYS_SDRAM_1_SIZE + SZ_256M) / SZ_32M - 1)
+
+       /* CS0 MRS: */
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 0, mr0_val))
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 1, mr1_val))
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 2, mr2_val))
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 3, 0))
+#if BANK_ADDR_BITS > 1
+       /* CS1 MRS: */
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(1, 0, mr0_val))
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(1, 1, mr1_val))
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(1, 2, mr2_val))
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(1, 3, 0))
+#endif
+
+       MXC_DCD_ITEM(MMDC1_MDREF, 0x0000c000) /* disable refresh */
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x00008020) /* issue one refresh cycle */
+
+       MXC_DCD_ITEM(MMDC1_MPODTCTRL, 0x00022222)
+       MXC_DCD_ITEM_64(MMDC2_MPODTCTRL, 0x00022222)
+
+       /* DDR3 calibration */
+       MXC_DCD_ITEM(MMDC1_MPPDCMPR2, 0x00000003) /* select default compare pattern for DQ calibration */
+       MXC_DCD_ITEM(MMDC1_MAPSR,     0x00001007)
+
+       /* ZQ calibration */
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008010) /* precharge all */
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008040) /* MRS: ZQ calibration */
+       MXC_DCD_ITEM(MMDC1_MPZQHWCTRL, 0xa1390001)
+
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPZQHWCTRL, 0x00010000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
+       MXC_DCD_ITEM(MMDC1_MPZQHWCTRL, 0xa1380000)
+
+#define WL_DLY_DQS_VAL 30
+#define WL_DLY_DQS0    (WL_DLY_DQS_VAL + 0)
+#define WL_DLY_DQS1    (WL_DLY_DQS_VAL + 0)
+#define WL_DLY_DQS2    (WL_DLY_DQS_VAL + 0)
+#define WL_DLY_DQS3    (WL_DLY_DQS_VAL + 0)
+#define WL_DLY_DQS4    (WL_DLY_DQS_VAL + 0)
+#define WL_DLY_DQS5    (WL_DLY_DQS_VAL + 0)
+#define WL_DLY_DQS6    (WL_DLY_DQS_VAL + 0)
+#define WL_DLY_DQS7    (WL_DLY_DQS_VAL + 0)
+       /* Write leveling */
+       MXC_DCD_ITEM(MMDC1_MPWLDECTRL0, (WL_DLY_DQS1 << 16) | (WL_DLY_DQS0 << 0))
+       MXC_DCD_ITEM_32(MMDC1_MPWLDECTRL1, (WL_DLY_DQS3 << 16) | (WL_DLY_DQS2 << 0))
+       MXC_DCD_ITEM_64(MMDC2_MPWLDECTRL0, (WL_DLY_DQS5 << 16) | (WL_DLY_DQS4 << 0))
+       MXC_DCD_ITEM_64(MMDC2_MPWLDECTRL1, (WL_DLY_DQS7 << 16) | (WL_DLY_DQS6 << 0))
+
+#if PHYS_SDRAM_1_WIDTH > 16
+#define DO_DDR_CALIB
+#endif
+       /* DQS gating calibration */
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 3, 4)) /* MRS: select MPR */
+#if BANK_ADDR_BITS > 1
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(1, 3, 4)) /* MRS: select MPR */
+#endif
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0_P, SDQS_MASK | 0x7000) /* enable Pullups on DQS pads */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P, SDQS_MASK | 0x7000)
+       MXC_DCD_ITEM_32(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2_P, SDQS_MASK | 0x7000)
+       MXC_DCD_ITEM_32(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3_P, SDQS_MASK | 0x7000)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4_P, SDQS_MASK | 0x7000)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P, SDQS_MASK | 0x7000)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P, SDQS_MASK | 0x7000)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P, SDQS_MASK | 0x7000)
+
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x00008020) /* issue one refresh cycle */
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
+
+       MXC_DCD_ITEM(MMDC1_MPRDDLCTL, 0x40404040) /* DQ RD Delay default values */
+       MXC_DCD_ITEM(MMDC1_MPWRDLCTL, 0x40404040) /* DQ WR Delay default values */
+       MXC_DCD_ITEM_64(MMDC2_MPRDDLCTL, 0x40404040) /* DQ RD Delay default values */
+       MXC_DCD_ITEM_64(MMDC2_MPWRDLCTL, 0x40404040) /* DQ WR Delay default values */
+#ifdef DO_DDR_CALIB
+       MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x80000000) /* issue fifo reset */
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x80000000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+       MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x80000000) /* issue 2nd fifo reset */
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x80000000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+       MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x50800000) /* choose 32 wait cycles and start DQS calib. */
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPDGCTRL0, 0x10001000)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+#else /* DO_DDR_CALIB */
+#define MPMUR_FRC_MSR  (1 << 11)
+       MXC_DCD_ITEM(MMDC1_MPDGCTRL0, 0x41e20160)
+       MXC_DCD_ITEM(MMDC1_MPDGCTRL1, 0x014d014f)
+       MXC_DCD_ITEM_64(MMDC2_MPDGCTRL0, 0x014f0150)
+       MXC_DCD_ITEM_64(MMDC2_MPDGCTRL1, 0x0144014a)
+#endif /* DO_DDR_CALIB */
+       /* DRAM_SDQS[0..7] pad config */
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0_P, SDQS_MASK)
+       MXC_DCD_ITEM(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1_P, SDQS_MASK)
+       MXC_DCD_ITEM_32(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2_P, SDQS_MASK)
+       MXC_DCD_ITEM_32(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3_P, SDQS_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4_P, SDQS_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5_P, SDQS_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6_P, SDQS_MASK)
+       MXC_DCD_ITEM_64(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7_P, SDQS_MASK)
+#ifdef DO_DDR_CALIB
+       /* Read delay calibration */
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
+       MXC_DCD_ITEM(MMDC1_MPRDDLHWCTL, 0x00000030) /* MPRDDLHWCTL: HW_WR_DL_CMP_CYC | HW_RD_DL_EN */
+       MXC_DCD_ITEM_64(MMDC2_MPRDDLHWCTL, 0x00000030) /* MPRDDLHWCTL: HW_WR_DL_CMP_CYC | HW_RD_DL_EN */
+       MXC_DCD_CMD_CHK_16(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPRDDLHWCTL, 0x00000013)
+       MXC_DCD_CMD_CHK_32(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPRDDLHWCTL, 0x0000001f)
+       MXC_DCD_CMD_CHK_64(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPRDDLHWCTL, 0x0000001f)
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+#else /* DO_DDR_CALIB */
+       MXC_DCD_ITEM(MMDC1_MPRDDLCTL, 0x4a4f4e4c)
+       MXC_DCD_ITEM_64(MMDC2_MPRDDLCTL, 0x4e50504a)
+#endif /* DO_DDR_CALIB */
+#ifdef DO_DDR_CALIB
+       /* Write delay calibration */
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
+       MXC_DCD_ITEM(MMDC1_MPWRDLHWCTL, 0x00000030) /* start WR DL calibration */
+       MXC_DCD_CMD_CHK_16(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPWRDLHWCTL, 0x00000013)
+       MXC_DCD_CMD_CHK_32(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MPWRDLHWCTL, 0x0000001f)
+#if PHYS_SDRAM_1_WIDTH == 64
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x04008050) /* precharge all to bank 0 */
+       MXC_DCD_ITEM(MMDC2_MPWRDLHWCTL, 0x00000030) /* start WR DL calibration */
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC2_MPWRDLHWCTL, 0x0000001f)
+#endif
+       MXC_DCD_CMD_WRT(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_WRITE)
+#else /* DO_DDR_CALIB */
+       MXC_DCD_ITEM(MMDC1_MPWRDLCTL, 0x3f3f3f3f)
+       MXC_DCD_ITEM_64(MMDC2_MPWRDLCTL, 0x3f3f3f3f)
+       MXC_DCD_ITEM(MMDC1_MPMUR0, MPMUR_FRC_MSR)
+#endif /* DO_DDR_CALIB */
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(0, 3, 0)) /* MRS: select normal data path */
+#if BANK_ADDR_BITS > 1
+       MXC_DCD_ITEM(MMDC1_MDSCR, MDSCR_MRS_VAL(1, 3, 0)) /* MRS: select normal data path */
+#endif
+       MXC_DCD_ITEM(MMDC1_MPZQHWCTRL, 0xa138002b)
+       MXC_DCD_ITEM(MMDC1_MDREF, (3 << 11) | (0 << 14)) /* 4 cycles per 64kHz period (3.9us) */
+       MXC_DCD_ITEM(MMDC1_MAPSR, 0x00001006)
+       MXC_DCD_ITEM(MMDC1_MDPDC, MDPDC_VAL_1)
+       MXC_DCD_ITEM_64(MMDC2_MDPDC, MDPDC_VAL_1)
+
+       /* MDSCR: Normal operation */
+       MXC_DCD_ITEM(MMDC1_MDSCR, 0x00000000)
+       MXC_DCD_CMD_CHK(MXC_DCD_CMD_SZ_WORD, MXC_DCD_CMD_FLAG_CHK_CLR, MMDC1_MDSCR, 0x00004000)
+       MXC_DCD_END
diff --git a/board/karo/tx6/ltc3676.c b/board/karo/tx6/ltc3676.c
new file mode 100644 (file)
index 0000000..53cf5e2
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+
+#include "pmic.h"
+
+#define LTC3676_BUCK1          0x01
+#define LTC3676_BUCK2          0x02
+#define LTC3676_BUCK3          0x03
+#define LTC3676_BUCK4          0x04
+#define LTC3676_DVB1A          0x0A
+#define LTC3676_DVB1B          0x0B
+#define LTC3676_DVB2A          0x0C
+#define LTC3676_DVB2B          0x0D
+#define LTC3676_DVB3A          0x0E
+#define LTC3676_DVB3B          0x0F
+#define LTC3676_DVB4A          0x10
+#define LTC3676_DVB4B          0x11
+#define LTC3676_MSKPG          0x13
+#define LTC3676_CLIRQ          0x1f
+
+#define LTC3676_BUCK_DVDT_FAST (1 << 0)
+#define LTC3676_BUCK_KEEP_ALIVE        (1 << 1)
+#define LTC3676_BUCK_CLK_RATE_LOW (1 << 2)
+#define LTC3676_BUCK_PHASE_SEL (1 << 3)
+#define LTC3676_BUCK_ENABLE_300        (1 << 4)
+#define LTC3676_BUCK_PULSE_SKIP        (0 << 5)
+#define LTC3676_BUCK_BURST_MODE        (1 << 5)
+#define LTC3676_BUCK_CONTINUOUS        (2 << 5)
+#define LTC3676_BUCK_ENABLE    (1 << 7)
+
+#define LTC3676_PGOOD_MASK     (1 << 5)
+
+#define LTC3676_MSKPG_BUCK1    (1 << 0)
+#define LTC3676_MSKPG_BUCK2    (1 << 1)
+#define LTC3676_MSKPG_BUCK3    (1 << 2)
+#define LTC3676_MSKPG_BUCK4    (1 << 3)
+#define LTC3676_MSKPG_LDO2     (1 << 5)
+#define LTC3676_MSKPG_LDO3     (1 << 6)
+#define LTC3676_MSKPG_LDO4     (1 << 7)
+
+#define VDD_IO_VAL             mV_to_regval(vout_to_vref(3300, 5))
+#define VDD_IO_VAL_LP          mV_to_regval(vout_to_vref(3100, 5))
+#define VDD_IO_VAL_2           mV_to_regval(vout_to_vref(3300, 5_2))
+#define VDD_IO_VAL_2_LP                mV_to_regval(vout_to_vref(3100, 5_2))
+#define VDD_SOC_VAL            mV_to_regval(vout_to_vref(1425, 6))
+#define VDD_SOC_VAL_LP         mV_to_regval(vout_to_vref(900, 6))
+#define VDD_DDR_VAL            mV_to_regval(vout_to_vref(1500, 7))
+#define VDD_DDR_VAL_LP         mV_to_regval(vout_to_vref(1500, 7))
+#define VDD_CORE_VAL           mV_to_regval(vout_to_vref(1425, 8))
+#define VDD_CORE_VAL_LP                mV_to_regval(vout_to_vref(900, 8))
+
+/* LDO1 */
+#define R1_1                   470
+#define R2_1                   150
+/* LDO4 */
+#define R1_4                   470
+#define R2_4                   150
+/* Buck1 */
+#define R1_5                   390
+#define R2_5                   110
+#define R1_5_2                 470
+#define R2_5_2                 150
+/* Buck2 (SOC) */
+#define R1_6                   150
+#define R2_6                   180
+/* Buck3 (DDR) */
+#define R1_7                   150
+#define R2_7                   140
+/* Buck4 (CORE) */
+#define R1_8                   150
+#define R2_8                   180
+
+/* calculate voltages in 10mV */
+#define R1(idx)                        R1_##idx
+#define R2(idx)                        R2_##idx
+
+#define v2r(v,n,m)             DIV_ROUND(((((v) < (n)) ? (n) : (v)) - (n)), (m))
+#define r2v(r,n,m)             (((r) * (m) + (n)) / 10)
+
+#define vout_to_vref(vout, idx)        ((vout) * R2(idx) / (R1(idx) + R2(idx)))
+#define vref_to_vout(vref, idx)        DIV_ROUND_UP((vref) * (R1(idx) + R2(idx)), R2(idx))
+
+#define mV_to_regval(mV)       v2r((mV) * 10, 4125, 125)
+#define regval_to_mV(r)                r2v(r, 4125, 125)
+
+static struct ltc3676_regs {
+       u8 addr;
+       u8 val;
+       u8 mask;
+} ltc3676_regs[] = {
+       { LTC3676_MSKPG, ~LTC3676_MSKPG_BUCK1, },
+       { LTC3676_DVB2B, VDD_SOC_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
+       { LTC3676_DVB3B, VDD_DDR_VAL_LP, ~0x3f, },
+       { LTC3676_DVB4B, VDD_CORE_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
+       { LTC3676_DVB2A, VDD_SOC_VAL, ~0x3f, },
+       { LTC3676_DVB3A, VDD_DDR_VAL, ~0x3f, },
+       { LTC3676_DVB4A, VDD_CORE_VAL, ~0x3f, },
+       { LTC3676_BUCK1, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
+       { LTC3676_BUCK2, LTC3676_BUCK_BURST_MODE, },
+       { LTC3676_BUCK3, LTC3676_BUCK_BURST_MODE, },
+       { LTC3676_BUCK4, LTC3676_BUCK_BURST_MODE, },
+       { LTC3676_CLIRQ, 0, }, /* clear interrupt status */
+};
+
+static struct ltc3676_regs ltc3676_regs_1[] = {
+       { LTC3676_DVB1B, VDD_IO_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
+       { LTC3676_DVB1A, VDD_IO_VAL, ~0x3f, },
+};
+
+static struct ltc3676_regs ltc3676_regs_2[] = {
+       { LTC3676_DVB1B, VDD_IO_VAL_2_LP | LTC3676_PGOOD_MASK, ~0x3f, },
+       { LTC3676_DVB1A, VDD_IO_VAL_2, ~0x3f, },
+};
+
+static int tx6_rev_2(void)
+{
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank5_regs *fuse = (void *)ocotp->bank[5].fuse_regs;
+       u32 pad_settings = readl(&fuse->pad_settings);
+
+       debug("Fuse pad_settings @ %p = %02x\n",
+               &fuse->pad_settings, pad_settings);
+       return pad_settings & 1;
+}
+
+static int ltc3676_setup_regs(uchar slave_addr, struct ltc3676_regs *r,
+                       size_t count)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < count; i++, r++) {
+#ifdef DEBUG
+               unsigned char value;
+
+               ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+               if ((value & ~r->mask) != r->val) {
+                       printf("Changing PMIC reg %02x from %02x to %02x\n",
+                               r->addr, value, r->val);
+               }
+               if (ret) {
+                       printf("%s: failed to read PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+#endif
+               ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+int ltc3676_pmic_setup(uchar slave_addr)
+{
+       int ret;
+       unsigned char value;
+
+       ret = i2c_read(slave_addr, 0x11, 1, &value, 1);
+       if (ret) {
+               printf("%s: i2c_read error: %d\n", __func__, ret);
+               return ret;
+       }
+
+       ret = ltc3676_setup_regs(slave_addr, ltc3676_regs,
+                               ARRAY_SIZE(ltc3676_regs));
+       if (ret)
+               return ret;
+
+       ret = i2c_read(slave_addr, LTC3676_DVB4A, 1, &value, 1);
+       if (ret == 0) {
+               printf("VDDCORE set to %umV\n",
+                       vref_to_vout(regval_to_mV(value), 8));
+       } else {
+               printf("Failed to read VDDCORE register setting\n");
+       }
+
+       ret = i2c_read(slave_addr, LTC3676_DVB2A, 1, &value, 1);
+       if (ret == 0) {
+               printf("VDDSOC  set to %umV\n",
+                       vref_to_vout(regval_to_mV(value), 6));
+       } else {
+               printf("Failed to read VDDSOC register setting\n");
+       }
+
+       if (tx6_rev_2()) {
+               ret = ltc3676_setup_regs(slave_addr, ltc3676_regs_2,
+                               ARRAY_SIZE(ltc3676_regs_2));
+
+               ret = i2c_read(slave_addr, LTC3676_DVB1A, 1, &value, 1);
+               if (ret == 0) {
+                       printf("VDDIO   set to %umV\n",
+                               vref_to_vout(regval_to_mV(value), 5_2));
+               } else {
+                       printf("Failed to read VDDIO register setting\n");
+               }
+       } else {
+               ret = ltc3676_setup_regs(slave_addr, ltc3676_regs_1,
+                               ARRAY_SIZE(ltc3676_regs_1));
+       }
+       return ret;
+}
diff --git a/board/karo/tx6/pmic.c b/board/karo/tx6/pmic.c
new file mode 100644 (file)
index 0000000..2743dad
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2015 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <i2c.h>
+
+#include "pmic.h"
+
+static struct {
+       uchar addr;
+       int (*init)(uchar addr);
+} i2c_addrs[] = {
+#ifdef CONFIG_LTC3676
+       { 0x3c, ltc3676_pmic_setup, },
+#endif
+#ifdef CONFIG_RN5T618
+       { 0x32, rn5t618_pmic_setup, },
+#endif
+#ifdef CONFIG_RN5T567
+       { 0x33, rn5t567_pmic_setup, },
+#endif
+};
+
+int tx6_pmic_init(void)
+{
+       int ret = -ENODEV;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(i2c_addrs); i++) {
+               ret = i2c_probe(i2c_addrs[i].addr);
+               if (ret == 0) {
+                       i2c_addrs[i].init(i2c_addrs[i].addr);
+                       break;
+               }
+       }
+       return ret;
+}
diff --git a/board/karo/tx6/pmic.h b/board/karo/tx6/pmic.h
new file mode 100644 (file)
index 0000000..4786eef
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+int ltc3676_pmic_setup(uchar addr);
+int rn5t618_pmic_setup(uchar addr);
+int rn5t567_pmic_setup(uchar addr);
+
+int tx6_pmic_init(void);
diff --git a/board/karo/tx6/rn5t567.c b/board/karo/tx6/rn5t567.c
new file mode 100644 (file)
index 0000000..6f79137
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#include "pmic.h"
+
+#define RN5T567_NOETIMSET      0x11
+#define RN5T567_LDORTC1_SLOT   0x2a
+#define RN5T567_DC1CTL         0x2c
+#define RN5T567_DC1CTL2                0x2d
+#define RN5T567_DC2CTL         0x2e
+#define RN5T567_DC2CTL2                0x2f
+#define RN5T567_DC3CTL         0x30
+#define RN5T567_DC3CTL2                0x31
+#define RN5T567_DC1DAC         0x36 /* CORE */
+#define RN5T567_DC2DAC         0x37 /* SOC */
+#define RN5T567_DC3DAC         0x38 /* DDR */
+#define RN5T567_DC1DAC_SLP     0x3b
+#define RN5T567_DC2DAC_SLP     0x3c
+#define RN5T567_DC3DAC_SLP     0x3d
+#define RN5T567_LDOEN1         0x44
+#define RN5T567_LDODIS         0x46
+#define RN5T567_LDOEN2         0x48
+#define RN5T567_LDO3DAC                0x4e /* IO */
+#define RN5T567_LDORTC1DAC     0x56 /* VBACKUP */
+
+#define NOETIMSET_DIS_OFF_NOE_TIM      (1 << 3)
+
+#define VDD_RTC_VAL            mV_to_regval_rtc(3000)
+#define VDD_HIGH_VAL           mV_to_regval3(3000)
+#define VDD_HIGH_VAL_LP                mV_to_regval3(3000)
+#define VDD_CORE_VAL           mV_to_regval(1350)              /* DCDC1 */
+#define VDD_CORE_VAL_LP                mV_to_regval(900)
+#define VDD_SOC_VAL            mV_to_regval(1350)              /* DCDC2 */
+#define VDD_SOC_VAL_LP         mV_to_regval(900)
+#define VDD_DDR_VAL            mV_to_regval(1350)              /* DCDC3 */
+#define VDD_DDR_VAL_LP         mV_to_regval(1350)
+
+/* calculate voltages in 10mV */
+#define v2r(v,n,m)             DIV_ROUND(((((v) < (n)) ? (n) : (v)) - (n)), (m))
+#define r2v(r,n,m)             (((r) * (m) + (n)) / 10)
+
+/* DCDC1-3 */
+#define mV_to_regval(mV)       v2r((mV) * 10, 6000, 125)
+#define regval_to_mV(r)                r2v(r, 6000, 125)
+
+/* LDO1-2 */
+#define mV_to_regval2(mV)      v2r((mV) * 10, 9000, 250)
+#define regval2_to_mV(r)       r2v(r, 9000, 250)
+
+/* LDO3 */
+#define mV_to_regval3(mV)      v2r((mV) * 10, 6000, 250)
+#define regval3_to_mV(r)       r2v(r, 6000, 250)
+
+/* LDORTC */
+#define mV_to_regval_rtc(mV)   v2r((mV) * 10, 17000, 250)
+#define regval_rtc_to_mV(r)    r2v(r, 17000, 250)
+
+static struct rn5t567_regs {
+       u8 addr;
+       u8 val;
+       u8 mask;
+} rn5t567_regs[] = {
+       { RN5T567_NOETIMSET, NOETIMSET_DIS_OFF_NOE_TIM | 0x5, },
+       { RN5T567_DC1DAC, VDD_CORE_VAL, },
+       { RN5T567_DC2DAC, VDD_SOC_VAL, },
+       { RN5T567_DC3DAC, VDD_DDR_VAL, },
+       { RN5T567_DC1DAC_SLP, VDD_CORE_VAL_LP, },
+       { RN5T567_DC2DAC_SLP, VDD_SOC_VAL_LP, },
+       { RN5T567_DC3DAC_SLP, VDD_DDR_VAL_LP, },
+       { RN5T567_LDOEN1, 0x01f, ~0x1f, },
+       { RN5T567_LDOEN2, 0x10, ~0x30, },
+       { RN5T567_LDODIS, 0x00, },
+       { RN5T567_LDO3DAC, VDD_HIGH_VAL, },
+       { RN5T567_LDORTC1DAC, VDD_RTC_VAL, },
+       { RN5T567_LDORTC1_SLOT, 0x0f, ~0x3f, },
+};
+
+static int rn5t567_setup_regs(uchar slave_addr, struct rn5t567_regs *r,
+                       size_t count)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < count; i++, r++) {
+#ifdef DEBUG
+               unsigned char value;
+
+               ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+               if ((value & ~r->mask) != r->val) {
+                       printf("Changing PMIC reg %02x from %02x to %02x\n",
+                               r->addr, value, r->val);
+               }
+               if (ret) {
+                       printf("%s: failed to read PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+#endif
+               ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+int rn5t567_pmic_setup(uchar slave_addr)
+{
+       int ret;
+       unsigned char value;
+
+       ret = i2c_read(slave_addr, 0x11, 1, &value, 1);
+       if (ret) {
+               printf("%s: i2c_read error: %d\n", __func__, ret);
+               return ret;
+       }
+
+       ret = rn5t567_setup_regs(slave_addr, rn5t567_regs,
+                               ARRAY_SIZE(rn5t567_regs));
+       if (ret)
+               return ret;
+
+       ret = i2c_read(slave_addr, RN5T567_DC1DAC, 1, &value, 1);
+       if (ret == 0) {
+               printf("VDDCORE set to %umV\n", regval_to_mV(value));
+       } else {
+               printf("Failed to read VDDCORE register setting\n");
+       }
+
+       ret = i2c_read(slave_addr, RN5T567_DC2DAC, 1, &value, 1);
+       if (ret == 0) {
+               printf("VDDSOC  set to %umV\n", regval_to_mV(value));
+       } else {
+               printf("Failed to read VDDSOC register setting\n");
+       }
+
+       return ret;
+}
diff --git a/board/karo/tx6/rn5t618.c b/board/karo/tx6/rn5t618.c
new file mode 100644 (file)
index 0000000..19aba87
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#include "pmic.h"
+
+#define RN5T618_NOETIMSET      0x11
+#define RN5T618_LDORTC1_SLOT   0x2a
+#define RN5T618_DC1CTL         0x2c
+#define RN5T618_DC1CTL2                0x2d
+#define RN5T618_DC2CTL         0x2e
+#define RN5T618_DC2CTL2                0x2f
+#define RN5T618_DC3CTL         0x30
+#define RN5T618_DC3CTL2                0x31
+#define RN5T618_DC1DAC         0x36 /* CORE */
+#define RN5T618_DC2DAC         0x37 /* SOC */
+#define RN5T618_DC3DAC         0x38 /* DDR */
+#define RN5T618_DC1DAC_SLP     0x3b
+#define RN5T618_DC2DAC_SLP     0x3c
+#define RN5T618_DC3DAC_SLP     0x3d
+#define RN5T618_LDOEN1         0x44
+#define RN5T618_LDODIS         0x46
+#define RN5T618_LDOEN2         0x48
+#define RN5T618_LDO3DAC                0x4e /* IO */
+#define RN5T618_LDORTCDAC      0x56 /* VBACKUP */
+
+#define VDD_RTC_VAL            mV_to_regval_rtc(3000)
+#define VDD_HIGH_VAL           mV_to_regval3(3000)
+#define VDD_HIGH_VAL_LP                mV_to_regval3(3000)
+#define VDD_CORE_VAL           mV_to_regval(1425)              /* DCDC1 */
+#define VDD_CORE_VAL_LP                mV_to_regval(900)
+#define VDD_SOC_VAL            mV_to_regval(1425)              /* DCDC2 */
+#define VDD_SOC_VAL_LP         mV_to_regval(900)
+#define VDD_DDR_VAL            mV_to_regval(1500)              /* DCDC3 */
+#define VDD_DDR_VAL_LP         mV_to_regval(1500)
+
+/* calculate voltages in 10mV */
+#define v2r(v,n,m)             DIV_ROUND(((((v) < (n)) ? (n) : (v)) - (n)), (m))
+#define r2v(r,n,m)             (((r) * (m) + (n)) / 10)
+
+/* DCDC1-3 */
+#define mV_to_regval(mV)       v2r((mV) * 10, 6000, 125)
+#define regval_to_mV(r)                r2v(r, 6000, 125)
+
+/* LDO1-2 */
+#define mV_to_regval2(mV)      v2r((mV) * 10, 9000, 250)
+#define regval2_to_mV(r)       r2v(r, 9000, 250)
+
+/* LDO3 */
+#define mV_to_regval3(mV)      v2r((mV) * 10, 6000, 250)
+#define regval3_to_mV(r)       r2v(r, 6000, 250)
+
+/* LDORTC */
+#define mV_to_regval_rtc(mV)   v2r((mV) * 10, 17000, 250)
+#define regval_rtc_to_mV(r)    r2v(r, 17000, 250)
+
+static struct rn5t618_regs {
+       u8 addr;
+       u8 val;
+       u8 mask;
+} rn5t618_regs[] = {
+       { RN5T618_NOETIMSET, 0, },
+       { RN5T618_DC1DAC, VDD_CORE_VAL, },
+       { RN5T618_DC2DAC, VDD_SOC_VAL, },
+       { RN5T618_DC3DAC, VDD_DDR_VAL, },
+       { RN5T618_DC1DAC_SLP, VDD_CORE_VAL_LP, },
+       { RN5T618_DC2DAC_SLP, VDD_SOC_VAL_LP, },
+       { RN5T618_DC3DAC_SLP, VDD_DDR_VAL_LP, },
+       { RN5T618_LDOEN1, 0x01f, ~0x1f, },
+       { RN5T618_LDOEN2, 0x10, ~0x30, },
+       { RN5T618_LDODIS, 0x00, },
+       { RN5T618_LDO3DAC, VDD_HIGH_VAL, },
+       { RN5T618_LDORTCDAC, VDD_RTC_VAL, },
+       { RN5T618_LDORTC1_SLOT, 0x0f, ~0x3f, },
+};
+
+static int rn5t618_setup_regs(uchar slave_addr, struct rn5t618_regs *r,
+                       size_t count)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < count; i++, r++) {
+#ifdef DEBUG
+               unsigned char value;
+
+               ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
+               if ((value & ~r->mask) != r->val) {
+                       printf("Changing PMIC reg %02x from %02x to %02x\n",
+                               r->addr, value, r->val);
+               }
+               if (ret) {
+                       printf("%s: failed to read PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+#endif
+               ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, r->addr, ret);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+int rn5t618_pmic_setup(uchar slave_addr)
+{
+       int ret;
+       unsigned char value;
+
+       ret = i2c_read(slave_addr, 0x11, 1, &value, 1);
+       if (ret) {
+               printf("%s: i2c_read error: %d\n", __func__, ret);
+               return ret;
+       }
+
+       ret = rn5t618_setup_regs(slave_addr, rn5t618_regs,
+                               ARRAY_SIZE(rn5t618_regs));
+       if (ret)
+               return ret;
+
+       ret = i2c_read(slave_addr, RN5T618_DC1DAC, 1, &value, 1);
+       if (ret == 0) {
+               printf("VDDCORE set to %umV\n", regval_to_mV(value));
+       } else {
+               printf("Failed to read VDDCORE register setting\n");
+       }
+
+       ret = i2c_read(slave_addr, RN5T618_DC2DAC, 1, &value, 1);
+       if (ret == 0) {
+               printf("VDDSOC  set to %umV\n", regval_to_mV(value));
+       } else {
+               printf("Failed to read VDDSOC register setting\n");
+       }
+
+       return ret;
+}
diff --git a/board/karo/tx6/tx6qdl.c b/board/karo/tx6/tx6qdl.c
new file mode 100644 (file)
index 0000000..15340db
--- /dev/null
@@ -0,0 +1,1326 @@
+/*
+ * Copyright (C) 2012-2015 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <common.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#include <lcd.h>
+#include <netdev.h>
+#include <mmc.h>
+#include <fsl_esdhc.h>
+#include <video_fb.h>
+#include <ipu.h>
+#include <mxcfb.h>
+#include <i2c.h>
+#include <linux/fb.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/sys_proto.h>
+
+#include "../common/karo.h"
+#include "pmic.h"
+
+#define __data __attribute__((section(".data")))
+
+#define TX6_FEC_RST_GPIO               IMX_GPIO_NR(7, 6)
+#define TX6_FEC_PWR_GPIO               IMX_GPIO_NR(3, 20)
+#define TX6_FEC_INT_GPIO               IMX_GPIO_NR(7, 1)
+#define TX6_LED_GPIO                   IMX_GPIO_NR(2, 20)
+
+#define TX6_LCD_PWR_GPIO               IMX_GPIO_NR(2, 31)
+#define TX6_LCD_RST_GPIO               IMX_GPIO_NR(3, 29)
+#define TX6_LCD_BACKLIGHT_GPIO         IMX_GPIO_NR(1, 1)
+
+#define TX6_RESET_OUT_GPIO             IMX_GPIO_NR(7, 12)
+
+#ifdef CONFIG_MX6_TEMPERATURE_MIN
+#define TEMPERATURE_MIN                        CONFIG_MX6_TEMPERATURE_MIN
+#else
+#define TEMPERATURE_MIN                        (-40)
+#endif
+#ifdef CONFIG_MX6_TEMPERATURE_HOT
+#define TEMPERATURE_HOT                        CONFIG_MX6_TEMPERATURE_HOT
+#else
+#define TEMPERATURE_HOT                        80
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define MUX_CFG_SION                   IOMUX_PAD(0, 0, IOMUX_CONFIG_SION, 0, 0, 0)
+
+enum {
+       MX6_PAD_DECL(GARBAGE, 0, 0, 0, 0, 0, 0)
+};
+
+static const iomux_v3_cfg_t const tx6qdl_pads[] = {
+       MX6_PAD_GARBAGE,
+#ifdef CONFIG_TX6_NAND_
+       /* NAND flash pads */
+       MX6_PAD_NANDF_CLE__NAND_CLE,
+       MX6_PAD_NANDF_ALE__NAND_ALE,
+       MX6_PAD_NANDF_WP_B__NAND_RESETN,
+       MX6_PAD_NANDF_RB0__NAND_READY0,
+       MX6_PAD_NANDF_CS0__NAND_CE0N,
+       MX6_PAD_SD4_CMD__NAND_RDN,
+       MX6_PAD_SD4_CLK__NAND_WRN,
+       MX6_PAD_NANDF_D0__NAND_D0,
+       MX6_PAD_NANDF_D1__NAND_D1,
+       MX6_PAD_NANDF_D2__NAND_D2,
+       MX6_PAD_NANDF_D3__NAND_D3,
+       MX6_PAD_NANDF_D4__NAND_D4,
+       MX6_PAD_NANDF_D5__NAND_D5,
+       MX6_PAD_NANDF_D6__NAND_D6,
+       MX6_PAD_NANDF_D7__NAND_D7,
+#endif
+       /* RESET_OUT */
+       MX6_PAD_GPIO_17__GPIO7_IO12,
+
+       /* UART pads */
+#if CONFIG_MXC_UART_BASE == UART1_BASE
+       MX6_PAD_SD3_DAT7__UART1_TX_DATA,
+       MX6_PAD_SD3_DAT6__UART1_RX_DATA,
+       MX6_PAD_SD3_DAT1__UART1_RTS_B,
+       MX6_PAD_SD3_DAT0__UART1_CTS_B,
+#endif
+#if CONFIG_MXC_UART_BASE == UART2_BASE
+       MX6_PAD_SD4_DAT4__UART2_RX_DATA,
+       MX6_PAD_SD4_DAT7__UART2_TX_DATA,
+       MX6_PAD_SD4_DAT5__UART2_RTS_B,
+       MX6_PAD_SD4_DAT6__UART2_CTS_B,
+#endif
+#if CONFIG_MXC_UART_BASE == UART3_BASE
+       MX6_PAD_EIM_D24__UART3_TX_DATA,
+       MX6_PAD_EIM_D25__UART3_RX_DATA,
+       MX6_PAD_SD3_RST__UART3_RTS_B,
+       MX6_PAD_SD3_DAT3__UART3_CTS_B,
+#endif
+       /* internal I2C */
+       MX6_PAD_EIM_D28__I2C1_SDA,
+       MX6_PAD_EIM_D21__I2C1_SCL,
+
+       /* FEC PHY GPIO functions */
+       MX6_PAD_EIM_D20__GPIO3_IO20 | MUX_CFG_SION, /* PHY POWER */
+       MX6_PAD_SD3_DAT2__GPIO7_IO06 | MUX_CFG_SION, /* PHY RESET */
+       MX6_PAD_SD3_DAT4__GPIO7_IO01, /* PHY INT */
+};
+
+static const iomux_v3_cfg_t const tx6qdl_fec_pads[] = {
+       /* FEC functions */
+       MX6_PAD_ENET_MDC__ENET_MDC,
+       MX6_PAD_ENET_MDIO__ENET_MDIO,
+       MX6_PAD_GPIO_16__ENET_REF_CLK,
+       MX6_PAD_ENET_RX_ER__ENET_RX_ER,
+       MX6_PAD_ENET_CRS_DV__ENET_RX_EN,
+       MX6_PAD_ENET_RXD1__ENET_RX_DATA1,
+       MX6_PAD_ENET_RXD0__ENET_RX_DATA0,
+       MX6_PAD_ENET_TX_EN__ENET_TX_EN,
+       MX6_PAD_ENET_TXD1__ENET_TX_DATA1,
+       MX6_PAD_ENET_TXD0__ENET_TX_DATA0,
+};
+
+static const struct gpio const tx6qdl_gpios[] = {
+       { TX6_RESET_OUT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "#RESET_OUT", },
+       { TX6_FEC_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "FEC PHY PWR", },
+       { TX6_FEC_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "FEC PHY RESET", },
+       { TX6_FEC_INT_GPIO, GPIOFLAG_INPUT, "FEC PHY INT", },
+};
+
+/*
+ * Functions
+ */
+/* placed in section '.data' to prevent overwriting relocation info
+ * overlayed with bss
+ */
+static u32 wrsr __attribute__((section(".data")));
+
+#define WRSR_POR                       (1 << 4)
+#define WRSR_TOUT                      (1 << 1)
+#define WRSR_SFTW                      (1 << 0)
+
+static void print_reset_cause(void)
+{
+       struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+       void __iomem *wdt_base = (void __iomem *)WDOG1_BASE_ADDR;
+       u32 srsr;
+       char *dlm = "";
+
+       printf("Reset cause: ");
+
+       srsr = readl(&src_regs->srsr);
+       wrsr = readw(wdt_base + 4);
+
+       if (wrsr & WRSR_POR) {
+               printf("%sPOR", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00004) {
+               printf("%sCSU", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00008) {
+               printf("%sIPP USER", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00010) {
+               if (wrsr & WRSR_SFTW) {
+                       printf("%sSOFT", dlm);
+                       dlm = " | ";
+               }
+               if (wrsr & WRSR_TOUT) {
+                       printf("%sWDOG", dlm);
+                       dlm = " | ";
+               }
+       }
+       if (srsr & 0x00020) {
+               printf("%sJTAG HIGH-Z", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x00040) {
+               printf("%sJTAG SW", dlm);
+               dlm = " | ";
+       }
+       if (srsr & 0x10000) {
+               printf("%sWARM BOOT", dlm);
+               dlm = " | ";
+       }
+       if (dlm[0] == '\0')
+               printf("unknown");
+
+       printf("\n");
+}
+
+static const char __data *tx6_mod_suffix;
+
+static void tx6qdl_print_cpuinfo(void)
+{
+       u32 cpurev = get_cpu_rev();
+       char *cpu_str = "?";
+
+       switch ((cpurev >> 12) & 0xff) {
+       case MXC_CPU_MX6SL:
+               cpu_str = "SL";
+               tx6_mod_suffix = "?";
+               break;
+       case MXC_CPU_MX6DL:
+               cpu_str = "DL";
+               tx6_mod_suffix = "U";
+               break;
+       case MXC_CPU_MX6SOLO:
+               cpu_str = "SOLO";
+               tx6_mod_suffix = "S";
+               break;
+       case MXC_CPU_MX6Q:
+               cpu_str = "Q";
+               tx6_mod_suffix = "Q";
+               break;
+       }
+
+       printf("CPU:   Freescale i.MX6%s rev%d.%d at %d MHz\n",
+               cpu_str,
+               (cpurev & 0x000F0) >> 4,
+               (cpurev & 0x0000F) >> 0,
+               mxc_get_clock(MXC_ARM_CLK) / 1000000);
+
+       print_reset_cause();
+#ifdef CONFIG_MX6_TEMPERATURE_HOT
+       check_cpu_temperature(1);
+#endif
+}
+
+int board_early_init_f(void)
+{
+       gpio_request_array(tx6qdl_gpios, ARRAY_SIZE(tx6qdl_gpios));
+       imx_iomux_v3_setup_multiple_pads(tx6qdl_pads, ARRAY_SIZE(tx6qdl_pads));
+
+       return 0;
+}
+
+#ifndef CONFIG_MX6_TEMPERATURE_HOT
+static bool tx6_temp_check_enabled = true;
+#else
+#define tx6_temp_check_enabled 0
+#endif
+
+int board_init(void)
+{
+       int ret;
+
+       /* Address of boot parameters */
+       gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000;
+       gd->bd->bi_arch_number = -1;
+
+       if (ctrlc() || (wrsr & WRSR_TOUT)) {
+               if (wrsr & WRSR_TOUT)
+                       printf("WDOG RESET detected; Skipping PMIC setup\n");
+               else
+                       printf("<CTRL-C> detected; safeboot enabled\n");
+#ifndef CONFIG_MX6_TEMPERATURE_HOT
+               tx6_temp_check_enabled = false;
+#endif
+               return 1;
+       }
+
+       ret = tx6_pmic_init();
+       if (ret) {
+               printf("Failed to setup PMIC voltages\n");
+               hang();
+       }
+       return 0;
+}
+
+int dram_init(void)
+{
+       /* dram_init must store complete ramsize in gd->ram_size */
+       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+                               PHYS_SDRAM_1_SIZE);
+       return 0;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+       gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1,
+                       PHYS_SDRAM_1_SIZE);
+#if CONFIG_NR_DRAM_BANKS > 1
+       gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
+       gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2,
+                       PHYS_SDRAM_2_SIZE);
+#endif
+}
+
+#ifdef CONFIG_CMD_MMC
+#define SD_PAD_CTRL (PAD_CTL_PUS_47K_UP |                      \
+       PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |         \
+       PAD_CTL_SRE_FAST)
+
+static const iomux_v3_cfg_t mmc0_pads[] = {
+       MX6_PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       /* SD1 CD */
+       MX6_PAD_SD3_CMD__GPIO7_IO02,
+};
+
+static const iomux_v3_cfg_t mmc1_pads[] = {
+       MX6_PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       /* SD2 CD */
+       MX6_PAD_SD3_CLK__GPIO7_IO03,
+};
+
+#ifdef CONFIG_TX6_EMMC
+static const iomux_v3_cfg_t mmc3_pads[] = {
+       MX6_PAD_SD4_CMD__SD4_CMD | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD4_CLK__SD4_CLK | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD4_DAT0__SD4_DATA0 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD4_DAT1__SD4_DATA1 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD4_DAT2__SD4_DATA2 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       MX6_PAD_SD4_DAT3__SD4_DATA3 | MUX_PAD_CTRL(SD_PAD_CTRL),
+       /* eMMC RESET */
+       MX6_PAD_NANDF_ALE__SD4_RESET,
+};
+#endif
+
+static struct tx6_esdhc_cfg {
+       const iomux_v3_cfg_t *pads;
+       int num_pads;
+       enum mxc_clock clkid;
+       struct fsl_esdhc_cfg cfg;
+       int cd_gpio;
+} tx6qdl_esdhc_cfg[] = {
+#ifdef CONFIG_TX6_EMMC
+       {
+               .pads = mmc3_pads,
+               .num_pads = ARRAY_SIZE(mmc3_pads),
+               .clkid = MXC_ESDHC4_CLK,
+               .cfg = {
+                       .esdhc_base = (void __iomem *)USDHC4_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = -EINVAL,
+       },
+#endif
+       {
+               .pads = mmc0_pads,
+               .num_pads = ARRAY_SIZE(mmc0_pads),
+               .clkid = MXC_ESDHC_CLK,
+               .cfg = {
+                       .esdhc_base = (void __iomem *)USDHC1_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(7, 2),
+       },
+       {
+               .pads = mmc1_pads,
+               .num_pads = ARRAY_SIZE(mmc1_pads),
+               .clkid = MXC_ESDHC2_CLK,
+               .cfg = {
+                       .esdhc_base = (void __iomem *)USDHC2_BASE_ADDR,
+                       .max_bus_width = 4,
+               },
+               .cd_gpio = IMX_GPIO_NR(7, 3),
+       },
+};
+
+static inline struct tx6_esdhc_cfg *to_tx6_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
+{
+       return container_of(cfg, struct tx6_esdhc_cfg, cfg);
+}
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+       struct tx6_esdhc_cfg *cfg = to_tx6_esdhc_cfg(mmc->priv);
+
+       if (cfg->cd_gpio < 0)
+               return 1;
+
+       debug("SD card %d is %spresent (GPIO %d)\n",
+               cfg - tx6qdl_esdhc_cfg,
+               gpio_get_value(cfg->cd_gpio) ? "NOT " : "",
+               cfg->cd_gpio);
+       return !gpio_get_value(cfg->cd_gpio);
+}
+
+int board_mmc_init(bd_t *bis)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(tx6qdl_esdhc_cfg); i++) {
+               struct mmc *mmc;
+               struct tx6_esdhc_cfg *cfg = &tx6qdl_esdhc_cfg[i];
+               int ret;
+
+               cfg->cfg.sdhc_clk = mxc_get_clock(cfg->clkid);
+               imx_iomux_v3_setup_multiple_pads(cfg->pads, cfg->num_pads);
+
+               if (cfg->cd_gpio >= 0) {
+                       ret = gpio_request_one(cfg->cd_gpio,
+                                       GPIOFLAG_INPUT, "MMC CD");
+                       if (ret) {
+                               printf("Error %d requesting GPIO%d_%d\n",
+                                       ret, cfg->cd_gpio / 32, cfg->cd_gpio % 32);
+                               continue;
+                       }
+               }
+
+               debug("%s: Initializing MMC slot %d\n", __func__, i);
+               fsl_esdhc_initialize(bis, &cfg->cfg);
+
+               mmc = find_mmc_device(i);
+               if (mmc == NULL)
+                       continue;
+               if (board_mmc_getcd(mmc))
+                       mmc_init(mmc);
+       }
+       return 0;
+}
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_FEC_MXC
+
+#define FEC_PAD_CTL    (PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
+                       PAD_CTL_SRE_FAST)
+#define FEC_PAD_CTL2   (PAD_CTL_DVS | PAD_CTL_SRE_FAST)
+#define GPIO_PAD_CTL   (PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+int board_eth_init(bd_t *bis)
+{
+       int ret;
+
+       /* delay at least 21ms for the PHY internal POR signal to deassert */
+       udelay(22000);
+
+       imx_iomux_v3_setup_multiple_pads(tx6qdl_fec_pads,
+                                       ARRAY_SIZE(tx6qdl_fec_pads));
+
+       /* Deassert RESET to the external phy */
+       gpio_set_value(TX6_FEC_RST_GPIO, 1);
+
+       ret = cpu_eth_init(bis);
+       if (ret)
+               printf("cpu_eth_init() failed: %d\n", ret);
+
+       return ret;
+}
+
+static void tx6_init_mac(void)
+{
+       u8 mac[ETH_ALEN];
+
+       imx_get_mac_from_fuse(-1, mac);
+       if (!is_valid_ether_addr(mac)) {
+               printf("No valid MAC address programmed\n");
+               return;
+       }
+
+       printf("MAC addr from fuse: %pM\n", mac);
+       eth_setenv_enetaddr("ethaddr", mac);
+}
+#else
+static inline void tx6_init_mac(void)
+{
+}
+#endif /* CONFIG_FEC_MXC */
+
+enum {
+       LED_STATE_INIT = -1,
+       LED_STATE_OFF,
+       LED_STATE_ON,
+};
+
+static inline int calc_blink_rate(void)
+{
+       if (!tx6_temp_check_enabled)
+               return CONFIG_SYS_HZ;
+
+       return CONFIG_SYS_HZ + CONFIG_SYS_HZ / 10 -
+               (check_cpu_temperature(0) - TEMPERATURE_MIN) * CONFIG_SYS_HZ /
+               (TEMPERATURE_HOT - TEMPERATURE_MIN);
+}
+
+void show_activity(int arg)
+{
+       static int led_state = LED_STATE_INIT;
+       static int blink_rate;
+       static ulong last;
+
+       if (led_state == LED_STATE_INIT) {
+               last = get_timer(0);
+               gpio_set_value(TX6_LED_GPIO, 1);
+               led_state = LED_STATE_ON;
+               blink_rate = calc_blink_rate();
+       } else {
+               if (get_timer(last) > blink_rate) {
+                       blink_rate = calc_blink_rate();
+                       last = get_timer_masked();
+                       if (led_state == LED_STATE_ON) {
+                               gpio_set_value(TX6_LED_GPIO, 0);
+                       } else {
+                               gpio_set_value(TX6_LED_GPIO, 1);
+                       }
+                       led_state = 1 - led_state;
+               }
+       }
+}
+
+static const iomux_v3_cfg_t stk5_pads[] = {
+       /* SW controlled LED on STK5 baseboard */
+       MX6_PAD_EIM_A18__GPIO2_IO20,
+
+       /* I2C bus on DIMM pins 40/41 */
+       MX6_PAD_GPIO_6__I2C3_SDA,
+       MX6_PAD_GPIO_3__I2C3_SCL,
+
+       /* TSC200x PEN IRQ */
+       MX6_PAD_EIM_D26__GPIO3_IO26,
+
+       /* EDT-FT5x06 Polytouch panel */
+       MX6_PAD_NANDF_CS2__GPIO6_IO15, /* IRQ */
+       MX6_PAD_EIM_A16__GPIO2_IO22, /* RESET */
+       MX6_PAD_EIM_A17__GPIO2_IO21, /* WAKE */
+
+       /* USBH1 */
+       MX6_PAD_EIM_D31__GPIO3_IO31, /* VBUSEN */
+       MX6_PAD_EIM_D30__GPIO3_IO30, /* OC */
+       /* USBOTG */
+       MX6_PAD_EIM_D23__GPIO3_IO23, /* USBOTG ID */
+       MX6_PAD_GPIO_7__GPIO1_IO07, /* VBUSEN */
+       MX6_PAD_GPIO_8__GPIO1_IO08, /* OC */
+};
+
+static const struct gpio stk5_gpios[] = {
+       { TX6_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
+
+       { IMX_GPIO_NR(3, 23), GPIOFLAG_INPUT, "USBOTG ID", },
+       { IMX_GPIO_NR(1, 8), GPIOFLAG_INPUT, "USBOTG OC", },
+       { IMX_GPIO_NR(1, 7), GPIOFLAG_OUTPUT_INIT_LOW, "USBOTG VBUS enable", },
+       { IMX_GPIO_NR(3, 30), GPIOFLAG_INPUT, "USBH1 OC", },
+       { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_LOW, "USBH1 VBUS enable", },
+};
+
+#ifdef CONFIG_LCD
+static u16 tx6_cmap[256];
+vidinfo_t panel_info = {
+       /* set to max. size supported by SoC */
+       .vl_col = 1920,
+       .vl_row = 1080,
+
+       .vl_bpix = LCD_COLOR32,    /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
+       .cmap = tx6_cmap,
+};
+
+static struct fb_videomode tx6_fb_modes[] = {
+#ifndef CONFIG_SYS_LVDS_IF
+       {
+               /* Standard VGA timing */
+               .name           = "VGA",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETV570 640 x 480 display. Syncs low active,
+                * DE high active, 115.2 mm x 86.4 mm display area
+                * VGA compatible timing
+                */
+               .name           = "ETV570",
+               .refresh        = 60,
+               .xres           = 640,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(25175),
+               .left_margin    = 114,
+               .hsync_len      = 30,
+               .right_margin   = 16,
+               .upper_margin   = 32,
+               .vsync_len      = 3,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0350G0DH6 320 x 240 display.
+                * 70.08 mm x 52.56 mm display area.
+                */
+               .name           = "ET0350",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6500),
+               .left_margin    = 68 - 34,
+               .hsync_len      = 34,
+               .right_margin   = 20,
+               .upper_margin   = 18 - 3,
+               .vsync_len      = 3,
+               .lower_margin   = 4,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0430G0DH6 480 x 272 display.
+                * 95.04 mm x 53.856 mm display area.
+                */
+               .name           = "ET0430",
+               .refresh        = 60,
+               .xres           = 480,
+               .yres           = 272,
+               .pixclock       = KHZ2PICOS(9000),
+               .left_margin    = 2,
+               .hsync_len      = 41,
+               .right_margin   = 2,
+               .upper_margin   = 2,
+               .vsync_len      = 10,
+               .lower_margin   = 2,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0500G0DH6 800 x 480 display.
+                * 109.6 mm x 66.4 mm display area.
+                */
+               .name           = "ET0500",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ETQ570G0DH6 320 x 240 display.
+                * 115.2 mm x 86.4 mm display area.
+                */
+               .name           = "ETQ570",
+               .refresh        = 60,
+               .xres           = 320,
+               .yres           = 240,
+               .pixclock       = KHZ2PICOS(6400),
+               .left_margin    = 38,
+               .hsync_len      = 30,
+               .right_margin   = 30,
+               .upper_margin   = 16, /* 15 according to datasheet */
+               .vsync_len      = 3, /* TVP -> 1>x>5 */
+               .lower_margin   = 4, /* 4.5 according to datasheet */
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+       {
+               /* Emerging ET070001DM6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET070001DM6",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 216 - 128,
+               .hsync_len      = 128,
+               .right_margin   = 1056 - 800 - 216,
+               .upper_margin   = 35 - 2,
+               .vsync_len      = 2,
+               .lower_margin   = 525 - 480 - 35,
+               .sync           = 0,
+       },
+#else
+       {
+               /* HannStar HSD100PXN1
+                * 202.7m mm x 152.06 mm display area.
+                */
+               .name           = "HSD100PXN1",
+               .refresh        = 60,
+               .xres           = 1024,
+               .yres           = 768,
+               .pixclock       = KHZ2PICOS(65000),
+               .left_margin    = 0,
+               .hsync_len      = 0,
+               .right_margin   = 320,
+               .upper_margin   = 0,
+               .vsync_len      = 0,
+               .lower_margin   = 38,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+#endif
+       {
+               /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+               .refresh        = 60,
+               .left_margin    = 48,
+               .hsync_len      = 96,
+               .right_margin   = 16,
+               .upper_margin   = 31,
+               .vsync_len      = 2,
+               .lower_margin   = 12,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+};
+
+static int lcd_enabled = 1;
+static int lcd_bl_polarity;
+
+static int lcd_backlight_polarity(void)
+{
+       return lcd_bl_polarity;
+}
+
+void lcd_enable(void)
+{
+       /* HACK ALERT:
+        * global variable from common/lcd.c
+        * Set to 0 here to prevent messages from going to LCD
+        * rather than serial console
+        */
+       lcd_is_enabled = 0;
+
+       karo_load_splashimage(1);
+
+       if (lcd_enabled) {
+               debug("Switching LCD on\n");
+               gpio_set_value(TX6_LCD_PWR_GPIO, 1);
+               udelay(100);
+               gpio_set_value(TX6_LCD_RST_GPIO, 1);
+               udelay(300000);
+               gpio_set_value(TX6_LCD_BACKLIGHT_GPIO,
+                       lcd_backlight_polarity());
+       }
+}
+
+void lcd_disable(void)
+{
+       if (lcd_enabled) {
+               printf("Disabling LCD\n");
+               ipuv3_fb_shutdown();
+       }
+}
+
+void lcd_panel_disable(void)
+{
+       if (lcd_enabled) {
+               debug("Switching LCD off\n");
+               gpio_set_value(TX6_LCD_BACKLIGHT_GPIO,
+                       !lcd_backlight_polarity());
+               gpio_set_value(TX6_LCD_RST_GPIO, 0);
+               gpio_set_value(TX6_LCD_PWR_GPIO, 0);
+       }
+}
+
+static const iomux_v3_cfg_t stk5_lcd_pads[] = {
+       /* LCD RESET */
+       MX6_PAD_EIM_D29__GPIO3_IO29,
+       /* LCD POWER_ENABLE */
+       MX6_PAD_EIM_EB3__GPIO2_IO31,
+       /* LCD Backlight (PWM) */
+       MX6_PAD_GPIO_1__GPIO1_IO01,
+
+#ifndef CONFIG_SYS_LVDS_IF
+       /* Display */
+       MX6_PAD_DISP0_DAT0__IPU1_DISP0_DATA00,
+       MX6_PAD_DISP0_DAT1__IPU1_DISP0_DATA01,
+       MX6_PAD_DISP0_DAT2__IPU1_DISP0_DATA02,
+       MX6_PAD_DISP0_DAT3__IPU1_DISP0_DATA03,
+       MX6_PAD_DISP0_DAT4__IPU1_DISP0_DATA04,
+       MX6_PAD_DISP0_DAT5__IPU1_DISP0_DATA05,
+       MX6_PAD_DISP0_DAT6__IPU1_DISP0_DATA06,
+       MX6_PAD_DISP0_DAT7__IPU1_DISP0_DATA07,
+       MX6_PAD_DISP0_DAT8__IPU1_DISP0_DATA08,
+       MX6_PAD_DISP0_DAT9__IPU1_DISP0_DATA09,
+       MX6_PAD_DISP0_DAT10__IPU1_DISP0_DATA10,
+       MX6_PAD_DISP0_DAT11__IPU1_DISP0_DATA11,
+       MX6_PAD_DISP0_DAT12__IPU1_DISP0_DATA12,
+       MX6_PAD_DISP0_DAT13__IPU1_DISP0_DATA13,
+       MX6_PAD_DISP0_DAT14__IPU1_DISP0_DATA14,
+       MX6_PAD_DISP0_DAT15__IPU1_DISP0_DATA15,
+       MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
+       MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
+       MX6_PAD_DISP0_DAT18__IPU1_DISP0_DATA18,
+       MX6_PAD_DISP0_DAT19__IPU1_DISP0_DATA19,
+       MX6_PAD_DISP0_DAT20__IPU1_DISP0_DATA20,
+       MX6_PAD_DISP0_DAT21__IPU1_DISP0_DATA21,
+       MX6_PAD_DISP0_DAT22__IPU1_DISP0_DATA22,
+       MX6_PAD_DISP0_DAT23__IPU1_DISP0_DATA23,
+       MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02, /* HSYNC */
+       MX6_PAD_DI0_PIN3__IPU1_DI0_PIN03, /* VSYNC */
+       MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15, /* OE_ACD */
+       MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, /* LSCLK */
+#endif
+};
+
+static const struct gpio stk5_lcd_gpios[] = {
+       { TX6_LCD_RST_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD RESET", },
+       { TX6_LCD_PWR_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LCD POWER", },
+       { TX6_LCD_BACKLIGHT_GPIO, GPIOFLAG_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
+};
+
+void lcd_ctrl_init(void *lcdbase)
+{
+       int color_depth = 24;
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       const char *vm;
+       unsigned long val;
+       int refresh = 60;
+       struct fb_videomode *p = &tx6_fb_modes[0];
+       struct fb_videomode fb_mode;
+       int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
+       int pix_fmt;
+       int lcd_bus_width;
+       unsigned long di_clk_rate = 65000000;
+
+       if (!lcd_enabled) {
+               debug("LCD disabled\n");
+               return;
+       }
+
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               setenv("splashimage", NULL);
+               return;
+       }
+
+       karo_fdt_move_fdt();
+       lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
+
+       if (video_mode == NULL) {
+               debug("Disabling LCD\n");
+               lcd_enabled = 0;
+               return;
+       }
+       vm = video_mode;
+       if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) {
+               p = &fb_mode;
+               debug("Using video mode from FDT\n");
+               vm += strlen(vm);
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
+       }
+       if (p->name != NULL)
+               debug("Trying compiled-in video modes\n");
+       while (p->name != NULL) {
+               if (strcmp(p->name, vm) == 0) {
+                       debug("Using video mode: '%s'\n", p->name);
+                       vm += strlen(vm);
+                       break;
+               }
+               p++;
+       }
+       if (*vm != '\0')
+               debug("Trying to decode video_mode: '%s'\n", vm);
+       while (*vm != '\0') {
+               if (*vm >= '0' && *vm <= '9') {
+                       char *end;
+
+                       val = simple_strtoul(vm, &end, 0);
+                       if (end > vm) {
+                               if (!xres_set) {
+                                       if (val > panel_info.vl_col)
+                                               val = panel_info.vl_col;
+                                       p->xres = val;
+                                       panel_info.vl_col = val;
+                                       xres_set = 1;
+                               } else if (!yres_set) {
+                                       if (val > panel_info.vl_row)
+                                               val = panel_info.vl_row;
+                                       p->yres = val;
+                                       panel_info.vl_row = val;
+                                       yres_set = 1;
+                               } else if (!bpp_set) {
+                                       switch (val) {
+                                       case 32:
+                                       case 24:
+                                               if (is_lvds())
+                                                       pix_fmt = IPU_PIX_FMT_LVDS888;
+                                               /* fallthru */
+                                       case 16:
+                                       case 8:
+                                               color_depth = val;
+                                               break;
+
+                                       case 18:
+                                               if (is_lvds()) {
+                                                       color_depth = val;
+                                                       break;
+                                               }
+                                               /* fallthru */
+                                       default:
+                                               printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+                                                       end - vm, vm, color_depth);
+                                       }
+                                       bpp_set = 1;
+                               } else if (!refresh_set) {
+                                       refresh = val;
+                                       refresh_set = 1;
+                               }
+                       }
+                       vm = end;
+               }
+               switch (*vm) {
+               case '@':
+                       bpp_set = 1;
+                       /* fallthru */
+               case '-':
+                       yres_set = 1;
+                       /* fallthru */
+               case 'x':
+                       xres_set = 1;
+                       /* fallthru */
+               case 'M':
+               case 'R':
+                       vm++;
+                       break;
+
+               default:
+                       if (*vm != '\0')
+                               vm++;
+               }
+       }
+       if (p->xres == 0 || p->yres == 0) {
+               printf("Invalid video mode: %s\n", getenv("video_mode"));
+               lcd_enabled = 0;
+               printf("Supported video modes are:");
+               for (p = &tx6_fb_modes[0]; p->name != NULL; p++) {
+                       printf(" %s", p->name);
+               }
+               printf("\n");
+               return;
+       }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
+               panel_info.vl_bpix = LCD_COLOR32;
+       }
+
+       p->pixclock = KHZ2PICOS(refresh *
+               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
+               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
+                               1000);
+       debug("Pixel clock set to %lu.%03lu MHz\n",
+               PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000);
+
+       if (p != &fb_mode) {
+               int ret;
+
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
+               if (ret)
+                       printf("Failed to create new display-timing node from '%s': %d\n",
+                               video_mode, ret);
+       }
+
+       gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
+                                       ARRAY_SIZE(stk5_lcd_pads));
+
+       lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24);
+       switch (lcd_bus_width) {
+       case 24:
+               pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS888 : IPU_PIX_FMT_RGB24;
+               break;
+
+       case 18:
+               pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS666 : IPU_PIX_FMT_RGB666;
+               break;
+
+       case 16:
+               if (!is_lvds()) {
+                       pix_fmt = IPU_PIX_FMT_RGB565;
+                       break;
+               }
+               /* fallthru */
+       default:
+               lcd_enabled = 0;
+               printf("Invalid %s bus width: %d\n", is_lvds() ? "LVDS" : "LCD",
+                       lcd_bus_width);
+               return;
+       }
+       if (is_lvds()) {
+               int lvds_mapping = karo_fdt_get_lvds_mapping(working_fdt, 0);
+               int lvds_chan_mask = karo_fdt_get_lvds_channels(working_fdt);
+               uint32_t gpr2;
+               uint32_t gpr3;
+
+               if (lvds_chan_mask == 0) {
+                       printf("No LVDS channel active\n");
+                       lcd_enabled = 0;
+                       return;
+               }
+
+               gpr2 = (lvds_mapping << 6) | (lvds_mapping << 8);
+               if (lcd_bus_width == 24)
+                       gpr2 |= (1 << 5) | (1 << 7);
+               gpr2 |= (lvds_chan_mask & 1) ? 1 << 0 : 0;
+               gpr2 |= (lvds_chan_mask & 2) ? 3 << 2 : 0;
+               debug("writing %08x to GPR2[%08x]\n", gpr2, IOMUXC_BASE_ADDR + 8);
+               writel(gpr2, IOMUXC_BASE_ADDR + 8);
+
+               gpr3 = readl(IOMUXC_BASE_ADDR + 0xc);
+               gpr3 &= ~((3 << 8) | (3 << 6));
+               writel(gpr3, IOMUXC_BASE_ADDR + 0xc);
+       }
+       if (karo_load_splashimage(0) == 0) {
+               int ret;
+
+               debug("Initializing LCD controller\n");
+               ret = ipuv3_fb_init(p, 0, pix_fmt,
+                               is_lvds() ? DI_PCLK_LDB : DI_PCLK_PLL3,
+                               di_clk_rate, -1);
+               if (ret) {
+                       printf("Failed to initialize FB driver: %d\n", ret);
+                       lcd_enabled = 0;
+               }
+       } else {
+               debug("Skipping initialization of LCD controller\n");
+       }
+}
+#else
+#define lcd_enabled 0
+#endif /* CONFIG_LCD */
+
+static void stk5_board_init(void)
+{
+       gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
+       imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+}
+
+static void stk5v3_board_init(void)
+{
+       stk5_board_init();
+}
+
+static void stk5v5_board_init(void)
+{
+       stk5_board_init();
+
+       gpio_request_one(IMX_GPIO_NR(4, 21), GPIOFLAG_OUTPUT_INIT_HIGH,
+                       "Flexcan Transceiver");
+       imx_iomux_v3_setup_pad(MX6_PAD_DISP0_DAT0__GPIO4_IO21);
+}
+
+static void tx6qdl_set_cpu_clock(void)
+{
+       unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+
+       if (cpu_clk == 0 || cpu_clk == mxc_get_clock(MXC_ARM_CLK) / 1000000)
+               return;
+
+       if (had_ctrlc() || (wrsr & WRSR_TOUT)) {
+               printf("%s detected; skipping cpu clock change\n",
+                       (wrsr & WRSR_TOUT) ? "WDOG RESET" : "<CTRL-C>");
+               return;
+       }
+       if (mxc_set_clock(CONFIG_SYS_MX6_HCLK, cpu_clk, MXC_ARM_CLK) == 0) {
+               cpu_clk = mxc_get_clock(MXC_ARM_CLK);
+               printf("CPU clock set to %lu.%03lu MHz\n",
+                       cpu_clk / 1000000, cpu_clk / 1000 % 1000);
+       } else {
+               printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk);
+       }
+}
+
+int board_late_init(void)
+{
+       int ret = 0;
+       const char *baseboard;
+
+       env_cleanup();
+
+       if (tx6_temp_check_enabled)
+               check_cpu_temperature(1);
+
+       tx6qdl_set_cpu_clock();
+
+       if (had_ctrlc())
+               setenv_ulong("safeboot", 1);
+       else if (wrsr & WRSR_TOUT)
+               setenv_ulong("wdreset", 1);
+       else
+               karo_fdt_move_fdt();
+
+       baseboard = getenv("baseboard");
+       if (!baseboard)
+               goto exit;
+
+       printf("Baseboard: %s\n", baseboard);
+
+       if (strncmp(baseboard, "stk5", 4) == 0) {
+               if ((strlen(baseboard) == 4) ||
+                       strcmp(baseboard, "stk5-v3") == 0) {
+                       stk5v3_board_init();
+               } else if (strcmp(baseboard, "stk5-v5") == 0) {
+                       const char *otg_mode = getenv("otg_mode");
+
+                       if (otg_mode && strcmp(otg_mode, "host") == 0) {
+                               printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
+                                       otg_mode, baseboard);
+                               setenv("otg_mode", "none");
+                       }
+                       stk5v5_board_init();
+               } else {
+                       printf("WARNING: Unsupported STK5 board rev.: %s\n",
+                               baseboard + 4);
+               }
+       } else {
+               printf("WARNING: Unsupported baseboard: '%s'\n",
+                       baseboard);
+               ret = -EINVAL;
+       }
+
+exit:
+       tx6_init_mac();
+
+       gpio_set_value(TX6_RESET_OUT_GPIO, 1);
+       clear_ctrlc();
+       return ret;
+}
+
+#ifdef CONFIG_TX6_NAND
+#define TX6_FLASH_SZ   (CONFIG_SYS_NAND_BLOCKS / 1024 - 1)
+#else
+#ifdef CONFIG_MMC_BOOT_SIZE
+#define TX6_FLASH_SZ   (CONFIG_MMC_BOOT_SIZE / 4096 + 2)
+#else
+#define TX6_FLASH_SZ   2
+#endif
+#endif /* CONFIG_TX6_NAND */
+
+#define TX6_DDR_SZ     (ffs(PHYS_SDRAM_1_WIDTH / 16) - 1)
+
+static char tx6_mem_table[] = {
+       '4', /* 256MiB SDRAM 16bit; 128MiB NAND */
+       '1', /* 512MiB SDRAM 32bit; 128MiB NAND */
+       '0', /* 1GiB SDRAM 64bit; 128MiB NAND */
+       '?', /* 256MiB SDRAM 16bit; 256MiB NAND */
+       '?', /* 512MiB SDRAM 32bit; 256MiB NAND */
+       '2', /* 1GiB SDRAM 64bit; 256MiB NAND */
+       '?', /* 256MiB SDRAM 16bit; 4GiB eMMC */
+       '5', /* 512MiB SDRAM 32bit; 4GiB eMMC */
+       '3', /* 1GiB SDRAM 64bit; 4GiB eMMC */
+       '?', /* 256MiB SDRAM 16bit; 8GiB eMMC */
+       '?', /* 512MiB SDRAM 32bit; 8GiB eMMC */
+       '0', /* 1GiB SDRAM 64bit; 8GiB eMMC */
+};
+
+static inline char tx6_mem_suffix(void)
+{
+       size_t mem_idx = (TX6_FLASH_SZ * 3) + TX6_DDR_SZ;
+
+       debug("TX6_DDR_SZ=%d TX6_FLASH_SZ=%d idx=%d\n",
+               TX6_DDR_SZ, TX6_FLASH_SZ, mem_idx);
+
+       if (mem_idx >= ARRAY_SIZE(tx6_mem_table))
+               return '?';
+
+       return tx6_mem_table[mem_idx];
+};
+
+static struct {
+       uchar addr;
+       uchar rev;
+} tx6_mod_revs[] = {
+       { 0x3c, 1, },
+       { 0x32, 2, },
+       { 0x33, 3, },
+};
+
+static int tx6_get_mod_rev(void)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(tx6_mod_revs); i++) {
+               int ret = i2c_probe(tx6_mod_revs[i].addr);
+               if (ret == 0) {
+                       debug("I2C probe succeeded for addr %02x\n", tx6_mod_revs[i].addr);
+                       return tx6_mod_revs[i].rev;
+               }
+               debug("I2C probe returned %d for addr %02x\n", ret,
+                       tx6_mod_revs[i].addr);
+       }
+       return 0;
+}
+
+int checkboard(void)
+{
+       u32 cpurev = get_cpu_rev();
+       int cpu_variant = (cpurev >> 12) & 0xff;
+
+       tx6qdl_print_cpuinfo();
+
+       i2c_init(CONFIG_SYS_I2C_SPEED, 0 /* unused */);
+
+       printf("Board: Ka-Ro TX6%s-%d%d%d%c\n",
+               tx6_mod_suffix,
+               cpu_variant == MXC_CPU_MX6Q ? 1 : 8,
+               is_lvds(), tx6_get_mod_rev(),
+               tx6_mem_suffix());
+
+       return 0;
+}
+
+#ifdef CONFIG_SERIAL_TAG
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank0_regs *fuse = (void *)ocotp->bank[0].fuse_regs;
+
+       serialnr->low = readl(&fuse->cfg0);
+       serialnr->high = readl(&fuse->cfg1);
+}
+#endif
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+#ifdef CONFIG_FDT_FIXUP_PARTITIONS
+#include <jffs2/jffs2.h>
+#include <mtd_node.h>
+static struct node_info nodes[] = {
+       { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, },
+};
+#else
+#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
+#endif
+
+static const char *tx6_touchpanels[] = {
+       "ti,tsc2007",
+       "edt,edt-ft5x06",
+       "eeti,egalax_ts",
+};
+
+int ft_board_setup(void *blob, bd_t *bd)
+{
+       const char *baseboard = getenv("baseboard");
+       int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = karo_get_vmode(getenv("video_mode"));
+       int ret;
+
+       ret = fdt_increase_size(blob, 4096);
+       if (ret) {
+               printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
+               return ret;
+       }
+       if (stk5_v5)
+               karo_fdt_enable_node(blob, "stk5led", 0);
+
+       fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+       fdt_fixup_ethernet(blob);
+
+       karo_fdt_fixup_touchpanel(blob, tx6_touchpanels,
+                               ARRAY_SIZE(tx6_touchpanels));
+       karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+
+       karo_fdt_update_fb_mode(blob, video_mode);
+
+       return 0;
+}
+#endif /* CONFIG_OF_BOARD_SETUP */
diff --git a/board/karo/tx6/u-boot.lds b/board/karo/tx6/u-boot.lds
new file mode 100644 (file)
index 0000000..4578feb
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * (C) Copyright 2012  Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+       . = 0x00000000;
+       .text :
+       {
+               *(.__image_copy_start)
+               *(.vectors)
+               CPUDIR/start.o (.text*)
+               . = 0x400;
+               KEEP(board/karo/tx6/lowlevel_init.o (.text*))
+               *(.text*)
+       }
+
+       . = ALIGN(4);
+       .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+
+       . = ALIGN(4);
+       .data : {
+               *(.data*)
+       }
+
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+
+       . = ALIGN(4);
+       .image_copy_end :
+       {
+               *(.__image_copy_end)
+       }
+
+       .rel_dyn_start :
+       {
+               *(.__rel_dyn_start)
+       }
+
+       .rel.dyn :
+       {
+               *(.rel*)
+       }
+
+       .rel_dyn_end :
+       {
+               *(.__rel_dyn_end)
+       }
+
+       .end :
+       {
+               *(.__end)
+       }
+
+       _image_binary_end = .;
+
+/*
+ * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
+ * __bss_base and __bss_limit are for linker only (overlay ordering)
+ */
+
+       .bss_start __rel_dyn_start (OVERLAY) : {
+               KEEP(*(.__bss_start));
+               __bss_base = .;
+       }
+
+       .bss __bss_base (OVERLAY) : {
+               *(.bss*)
+               . = ALIGN(4);
+               __bss_limit = .;
+       }
+       .bss_end __bss_limit (OVERLAY) : {
+               KEEP(*(.__bss_end));
+       }
+       .dynsym _image_binary_end : { *(.dynsym) }
+       .dynbss : { *(.dynbss) }
+       .dynstr : { *(.dynstr*) }
+       .dynamic : { *(.dynamic*) }
+       .plt : { *(.plt*) }
+       .interp : { *(.interp*) }
+       .gnu.hash : { *(.gnu.hash) }
+       .gnu : { *(.gnu*) }
+       .ARM.exidx : { *(.ARM.exidx*) }
+       .gnu.linkonce.armexidx : { *(.gnu.linkonce.armexidx.*) }
+
+/*
+       /DISCARD/ : { *(.bss*) }
+       /DISCARD/ : { *(.dynstr*) }
+       /DISCARD/ : { *(.dynsym*) }
+       /DISCARD/ : { *(.dynamic*) }
+       /DISCARD/ : { *(.hash*) }
+       /DISCARD/ : { *(.plt*) }
+       /DISCARD/ : { *(.interp*) }
+       /DISCARD/ : { *(.gnu*) }
+*/
+}
index 1075c6589d5d2ecda1a94301ee4d2b6f32eb9434..18158806f57066aef15e1430afb6ba1def9593c4 100644 (file)
@@ -71,7 +71,7 @@ static iomux_v3_cfg_t const usdhc1_pads[] = {
        MX6_PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        /* Carrier MicroSD Card Detect */
-       MX6_PAD_GPIO_2__GPIO1_IO02      | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_GPIO_2__GPIO1_IO02,
 };
 
 static iomux_v3_cfg_t const usdhc3_pads[] = {
@@ -82,7 +82,7 @@ static iomux_v3_cfg_t const usdhc3_pads[] = {
        MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
        /* SOM MicroSD Card Detect */
-       MX6_PAD_EIM_DA9__GPIO3_IO09     | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_DA9__GPIO3_IO09,
 };
 
 static iomux_v3_cfg_t const enet_pads[] = {
@@ -102,7 +102,7 @@ static iomux_v3_cfg_t const enet_pads[] = {
        MX6_PAD_RGMII_RD3__RGMII_RD3    | MUX_PAD_CTRL(ENET_PAD_CTRL),
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
        /* AR8031 PHY Reset */
-       MX6_PAD_EIM_D29__GPIO3_IO29             | MUX_PAD_CTRL(NO_PAD_CTRL),
+       MX6_PAD_EIM_D29__GPIO3_IO29,
 };
 
 static void setup_iomux_uart(void)
@@ -262,10 +262,8 @@ static iomux_v3_cfg_t const fwadapt_7wvga_pads[] = {
        MX6_PAD_DISP0_DAT16__IPU1_DISP0_DATA16,
        MX6_PAD_DISP0_DAT17__IPU1_DISP0_DATA17,
 
-       MX6_PAD_SD4_DAT2__GPIO2_IO10
-               | MUX_PAD_CTRL(NO_PAD_CTRL), /* DISP0_BKLEN */
-       MX6_PAD_SD4_DAT3__GPIO2_IO11
-               | MUX_PAD_CTRL(NO_PAD_CTRL), /* DISP0_VDDEN */
+       MX6_PAD_SD4_DAT2__GPIO2_IO10, /* DISP0_BKLEN */
+       MX6_PAD_SD4_DAT3__GPIO2_IO11, /* DISP0_VDDEN */
 };
 
 static void do_enable_hdmi(struct display_info_t const *dev)
index fd84fa08bd3efc2569ac4200684f26abca5ac205..d4130ceb069908c965e57faf27bae09f754b59a2 100644 (file)
@@ -53,6 +53,17 @@ config CMD_BOOTM
        help
          Boot an application image from the memory.
 
+config CMD_BOOTZ
+       bool "bootz"
+       default y
+       help
+         Boot a Linux kernel zImage.
+
+config CMD_BOOTCE
+       bool "bootce"
+       help
+         Boot a WindowsCE image.
+
 config CMD_GO
        bool "go"
        default y
@@ -81,6 +92,17 @@ config CMD_XIMG
 
 endmenu
 
+menu "DTB support"
+
+config OF_LIBFDT
+       bool "Enable FDT commands"
+
+config OF_BOARD_SETUP
+       bool "Support DT modifications by board code"
+       depends on OF_LIBFDT
+
+endmenu
+
 menu "Environment commands"
 
 config CMD_EXPORTENV
@@ -107,6 +129,26 @@ config CMD_SAVEENV
 
 endmenu
 
+menu "Environment configuration settings"
+
+choice
+       prompt "Select environment non-volatile storage"
+
+config ENV_IS_NOWHERE
+       bool "do not store environment"
+
+config ENV_IS_IN_NAND
+       bool "store environment in NAND"
+       depends on NAND
+
+config ENV_IS_IN_MMC
+       bool "store environment in MMC"
+       depends on MMC
+
+endchoice
+
+endmenu
+
 menu "Memory commands"
 
 config CMD_MEMORY
@@ -171,11 +213,33 @@ config CMD_FLASH
            erase - FLASH memory
            protect - enable or disable FLASH write protection
 
+config MTD_DEVICE
+       bool "MTD device support"
+
+config CMD_MTDPARTS
+       bool "MTD partitioning support"
+       default y
+       depends on MTD_DEVICE && (CMD_FLASH || CMD_NAND)
+
 config CMD_NAND
        bool "nand"
        help
          NAND support.
 
+config CMD_NAND_TRIMFFS
+       bool "Enable nand write.trimffs command"
+       help
+         Enable command to leave page sized runs of 0xff patterns in
+         erased state rather than overwriting them. This is required
+         for using NAND flash filesystems on NAND controllers with
+         a non-0xff ECC code for all 0xff data.
+
+config CMD_MMC
+       bool "mmc/sd"
+       select PARTITIONS
+       help
+         MMC/SD support.
+
 config CMD_SPI
        bool "sspi"
        help
@@ -286,6 +350,11 @@ endmenu
 
 menu "Misc commands"
 
+config CMD_CACHE
+       bool "cache control"
+       help
+         Enable commands to switch data cache on/off.
+
 config CMD_TIME
        bool "time"
        help
index 9579ab4c982287f6913beeff41b92b3a85731cae..fcdb749fd6d94fff031cadbfffc1ccb1e51779e3 100644 (file)
@@ -65,6 +65,7 @@ obj-$(CONFIG_CMD_SOURCE) += cmd_source.o
 obj-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 obj-$(CONFIG_CMD_BEDBUG) += bedbug.o cmd_bedbug.o
 obj-$(CONFIG_CMD_BMP) += cmd_bmp.o
+obj-$(CONFIG_CMD_BOOTCE) += cmd_bootce.o
 obj-$(CONFIG_CMD_BOOTMENU) += cmd_bootmenu.o
 obj-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
 obj-$(CONFIG_CMD_BOOTSTAGE) += cmd_bootstage.o
diff --git a/common/cmd_bootce.c b/common/cmd_bootce.c
new file mode 100644 (file)
index 0000000..a95f163
--- /dev/null
@@ -0,0 +1,1038 @@
+/*
+ * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ * based on: code from RedBoot (C) Uwe Steinkohl <US@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <wince.h>
+#include <nand.h>
+#include <malloc.h>
+#include <asm/errno.h>
+#include <jffs2/load_kernel.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define WINCE_VRAM_BASE                0x80000000
+#define CE_FIX_ADDRESS(a)      ((void *)((a) - WINCE_VRAM_BASE + CONFIG_SYS_SDRAM_BASE))
+
+#ifndef INT_MAX
+#define INT_MAX                        ((int)(~0U >> 1))
+#endif
+
+/* Bin image parse states */
+#define CE_PS_RTI_ADDR         0
+#define CE_PS_RTI_LEN          1
+#define CE_PS_E_ADDR           2
+#define CE_PS_E_LEN            3
+#define CE_PS_E_CHKSUM         4
+#define CE_PS_E_DATA           5
+
+#define CE_MIN(a, b)           (((a) < (b)) ? (a) : (b))
+#define CE_MAX(a, b)           (((a) > (b)) ? (a) : (b))
+
+static ce_bin __attribute__ ((aligned (32))) g_bin;
+static ce_net __attribute__ ((aligned (32))) g_net;
+static IPaddr_t server_ip;
+
+static void ce_init_bin(ce_bin *bin, unsigned char *dataBuffer)
+{
+       memset(bin, 0, sizeof(*bin));
+
+       bin->data = dataBuffer;
+       bin->parseState = CE_PS_RTI_ADDR;
+       bin->parsePtr = (unsigned char *)bin;
+}
+
+static int ce_is_bin_image(void *image, int imglen)
+{
+       if (imglen < CE_BIN_SIGN_LEN) {
+               return 0;
+       }
+
+       return memcmp(image, CE_BIN_SIGN, CE_BIN_SIGN_LEN) == 0;
+}
+
+static const struct ce_magic {
+       char magic[8];
+       size_t size;
+       ce_std_driver_globals drv_glb;
+} ce_magic_template = {
+       .magic = "KARO_CE6",
+       .size = sizeof(ce_std_driver_globals),
+       .drv_glb = {
+               .header = {
+                       .signature = STD_DRV_GLB_SIGNATURE,
+                       .oalVersion = 1,
+                       .bspVersion = 2,
+               },
+       },
+};
+
+#ifdef DEBUG
+static void __attribute__((unused)) ce_dump_block(void *ptr, int length)
+{
+       char *p = ptr;
+       int i;
+       int j;
+
+       for (i = 0; i < length; i++) {
+               if (!(i % 16)) {
+                       printf("\n%p: ", ptr + i);
+               }
+
+               printf("%02x ", p[i]);
+               if (!((i + 1) % 16)){
+                       printf("      ");
+                       for (j = i - 15; j <= i; j++){
+                               if((p[j] > 0x1f) && (p[j] < 0x7f)) {
+                                       printf("%c", p[j]);
+                               } else {
+                                       printf(".");
+                               }
+                       }
+               }
+       }
+       printf("\n");
+}
+#else
+static inline void ce_dump_block(void *ptr, int length)
+{
+}
+#endif
+
+static void ce_setup_std_drv_globals(ce_std_driver_globals *std_drv_glb)
+{
+       char *mtdparts = getenv("mtdparts");
+       size_t max_len = ALIGN((unsigned long)std_drv_glb, SZ_4K) -
+               (unsigned long)&std_drv_glb->mtdparts;
+
+       if (eth_get_dev()) {
+               memcpy(&std_drv_glb->kitl.mac, eth_get_dev()->enetaddr,
+                       sizeof(std_drv_glb->kitl.mac));
+       }
+       snprintf(std_drv_glb->deviceId, sizeof(std_drv_glb->deviceId),
+               "Triton%02X", eth_get_dev()->enetaddr[5]);
+
+       NetCopyIP(&std_drv_glb->kitl.ipAddress, &NetOurIP);
+       std_drv_glb->kitl.ipMask = getenv_IPaddr("netmask");
+       std_drv_glb->kitl.ipRoute = getenv_IPaddr("gatewayip");
+
+       if (mtdparts) {
+               strncpy(std_drv_glb->mtdparts, mtdparts, max_len);
+               std_drv_glb->mtdparts[max_len - 1] = '\0';
+       } else {
+               printf("Failed to get mtdparts environment variable\n");
+       }
+}
+
+static void ce_init_drv_globals(void)
+{
+       struct ce_magic *ce_magic = (void *)CONFIG_SYS_SDRAM_BASE + 0x160;
+       ce_std_driver_globals *std_drv_glb = &ce_magic->drv_glb;
+
+       debug("Copying CE MAGIC from %p to %p..%p\n",
+               &ce_magic_template, ce_magic,
+               (void *)ce_magic + sizeof(*ce_magic) - 1);
+       memcpy(ce_magic, &ce_magic_template, sizeof(*ce_magic));
+
+       ce_setup_std_drv_globals(std_drv_glb);
+       ce_magic->size = sizeof(*std_drv_glb) +
+               strlen(std_drv_glb->mtdparts) + 1;
+       ce_dump_block(ce_magic, offsetof(struct ce_magic, drv_glb) +
+               ce_magic->size);
+}
+
+static void ce_prepare_run_bin(ce_bin *bin)
+{
+       /* Clear os RAM area (if needed) */
+       if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
+               debug("cleaning memory from %p to %p\n",
+                       bin->eRamStart, bin->eRamStart + bin->eRamLen);
+
+               printf("Preparing clean boot ... ");
+               memset(bin->eRamStart, 0, bin->eRamLen);
+               printf("ok\n");
+       }
+
+       ce_init_drv_globals();
+
+       /*
+        * Make sure, all the above makes it into SDRAM because
+        * WinCE switches the cache & MMU off, obviously without
+        * flushing it first!
+        */
+       flush_dcache_all();
+}
+
+static int ce_lookup_ep_bin(ce_bin *bin)
+{
+       ce_rom_hdr *header;
+       ce_toc_entry *tentry;
+       e32_rom *e32;
+       unsigned int i;
+       uint32_t *sig = (uint32_t *)(bin->rtiPhysAddr + ROM_SIGNATURE_OFFSET);
+
+       debug("Looking for TOC signature at %p\n", sig);
+
+       /* Check image Table Of Contents (TOC) signature */
+       if (*sig != ROM_SIGNATURE) {
+               printf("Error: Did not find image TOC signature!\n");
+               printf("Expected %08x at address %p; found %08x instead\n",
+                       ROM_SIGNATURE, sig, *sig);
+               return 0;
+       }
+
+       /* Lookup entry point */
+       header = CE_FIX_ADDRESS(*(unsigned int *)(bin->rtiPhysAddr +
+                                               ROM_SIGNATURE_OFFSET +
+                                               sizeof(unsigned int)));
+       tentry = (ce_toc_entry *)(header + 1);
+
+       for (i = 0; i < header->nummods; i++) {
+               // Look for 'nk.exe' module
+               if (strcmp(CE_FIX_ADDRESS(tentry[i].fileName), "nk.exe") == 0) {
+                       // Save entry point and RAM addresses
+
+                       e32 = CE_FIX_ADDRESS(tentry[i].e32Offset);
+
+                       bin->eEntryPoint = CE_FIX_ADDRESS(tentry[i].loadOffset) +
+                               e32->e32_entryrva;
+                       bin->eRamStart = CE_FIX_ADDRESS(header->ramStart);
+                       bin->eRamLen = header->ramEnd - header->ramStart;
+                       return 1;
+               }
+       }
+
+       // Error: Did not find 'nk.exe' module
+       return 0;
+}
+
+static int ce_parse_bin(ce_bin *bin)
+{
+       unsigned char *pbData = bin->data;
+       int len = bin->dataLen;
+       int copyLen;
+
+       debug("starting ce image parsing:\n\tbin->binLen: 0x%08X\n", bin->binLen);
+
+       if (len) {
+               if (bin->binLen == 0) {
+                       // Check for the .BIN signature first
+                       if (!ce_is_bin_image(pbData, len)) {
+                               printf("Error: Invalid or corrupted .BIN image!\n");
+                               return CE_PR_ERROR;
+                       }
+
+                       printf("Loading Windows CE .BIN image ...\n");
+                       // Skip signature
+                       len -= CE_BIN_SIGN_LEN;
+                       pbData += CE_BIN_SIGN_LEN;
+               }
+
+               while (len) {
+                       switch (bin->parseState) {
+                       case CE_PS_RTI_ADDR:
+                       case CE_PS_RTI_LEN:
+                       case CE_PS_E_ADDR:
+                       case CE_PS_E_LEN:
+                       case CE_PS_E_CHKSUM:
+                               copyLen = CE_MIN(sizeof(unsigned int) - bin->parseLen, len);
+                               memcpy(&bin->parsePtr[bin->parseLen], pbData, copyLen);
+
+                               bin->parseLen += copyLen;
+                               len -= copyLen;
+                               pbData += copyLen;
+
+                               if (bin->parseLen == sizeof(unsigned int)) {
+                                       if (bin->parseState == CE_PS_RTI_ADDR)
+                                               bin->rtiPhysAddr = CE_FIX_ADDRESS(bin->rtiPhysAddr);
+                                       else if (bin->parseState == CE_PS_E_ADDR &&
+                                               bin->ePhysAddr)
+                                               bin->ePhysAddr = CE_FIX_ADDRESS(bin->ePhysAddr);
+
+                                       bin->parseState++;
+                                       bin->parseLen = 0;
+                                       bin->parsePtr += sizeof(unsigned int);
+
+                                       if (bin->parseState == CE_PS_E_DATA) {
+                                               if (bin->ePhysAddr) {
+                                                       bin->parsePtr = bin->ePhysAddr;
+                                                       bin->parseChkSum = 0;
+                                               } else {
+                                                       /* EOF */
+                                                       len = 0;
+                                                       bin->endOfBin = 1;
+                                               }
+                                       }
+                               }
+                               break;
+
+                       case CE_PS_E_DATA:
+                               debug("ePhysAddr=%p physlen=%08x parselen=%08x\n",
+                                       bin->ePhysAddr, bin->ePhysLen, bin->parseLen);
+                               if (bin->ePhysAddr) {
+                                       copyLen = CE_MIN(bin->ePhysLen - bin->parseLen, len);
+                                       bin->parseLen += copyLen;
+                                       len -= copyLen;
+
+                                       while (copyLen--) {
+                                               bin->parseChkSum += *pbData;
+                                               *bin->parsePtr++ = *pbData++;
+                                       }
+
+                                       if (bin->parseLen == bin->ePhysLen) {
+                                               printf("Section [%02d]: address %p, size 0x%08X, checksum %s\n",
+                                                       bin->section,
+                                                       bin->ePhysAddr,
+                                                       bin->ePhysLen,
+                                                       (bin->eChkSum == bin->parseChkSum) ? "ok" : "fail");
+
+                                               if (bin->eChkSum != bin->parseChkSum) {
+                                                       printf("Error: Checksum error, corrupted .BIN file!\n");
+                                                       printf("checksum calculated: 0x%08x from file: 0x%08x\n",
+                                                               bin->parseChkSum, bin->eChkSum);
+                                                       bin->binLen = 0;
+                                                       return CE_PR_ERROR;
+                                               }
+
+                                               bin->section++;
+                                               bin->parseState = CE_PS_E_ADDR;
+                                               bin->parseLen = 0;
+                                               bin->parsePtr = (unsigned char *)&bin->ePhysAddr;
+                                       }
+                               } else {
+                                       bin->parseLen = 0;
+                                       bin->endOfBin = 1;
+                                       len = 0;
+                               }
+                               break;
+                       }
+               }
+       }
+
+       if (bin->endOfBin) {
+               if (!ce_lookup_ep_bin(bin)) {
+                       printf("Error: entry point not found!\n");
+                       bin->binLen = 0;
+                       return CE_PR_ERROR;
+               }
+
+               printf("Entry point: %p, address range: %p-%p\n",
+                       bin->eEntryPoint,
+                       bin->rtiPhysAddr,
+                       bin->rtiPhysAddr + bin->rtiPhysLen);
+
+               return CE_PR_EOF;
+       }
+
+       /* Need more data */
+       bin->binLen += bin->dataLen;
+       return CE_PR_MORE;
+}
+
+static int ce_bin_load(void *image, int imglen)
+{
+       ce_init_bin(&g_bin, image);
+       g_bin.dataLen = imglen;
+       if (ce_parse_bin(&g_bin) == CE_PR_EOF) {
+               ce_prepare_run_bin(&g_bin);
+               return 1;
+       }
+
+       return 0;
+}
+
+static void ce_run_bin(void (*entry)(void))
+{
+       printf("Launching Windows CE ...\n");
+#ifdef TEST_LAUNCH
+return;
+#endif
+       entry();
+}
+
+static int do_bootce(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       void *addr;
+       size_t image_size;
+
+       if (argc > 1) {
+               if (strcmp(argv[1], "-i") == 0) {
+                       ce_init_drv_globals();
+                       return CMD_RET_SUCCESS;
+               }
+               addr = (void *)simple_strtoul(argv[1], NULL, 16);
+               image_size = INT_MAX;           /* actually we do not know the image size */
+       } else if (getenv("fileaddr") != NULL) {
+               addr = (void *)getenv_ulong("fileaddr", 16, 0);
+               image_size = getenv_ulong("filesize", 16, INT_MAX);
+       } else {
+               return CMD_RET_USAGE;
+       }
+
+       printf ("## Booting Windows CE Image from address %p ...\n", addr);
+
+       /* check if there is a valid windows CE image */
+       if (ce_is_bin_image(addr, image_size)) {
+               if (!ce_bin_load(addr, image_size)) {
+                       /* Ops! Corrupted .BIN image! */
+                       /* Handle error here ...      */
+                       printf("corrupted .BIN image !!!\n");
+                       return CMD_RET_FAILURE;
+               }
+               if (getenv_yesno("autostart") != 1) {
+                       /*
+                        * just use bootce to load the image to SDRAM;
+                        * Do not start it automatically.
+                        */
+                       setenv_addr("fileaddr", g_bin.eEntryPoint);
+                       return CMD_RET_SUCCESS;
+               }
+               ce_run_bin(g_bin.eEntryPoint);          /* start the image */
+       } else {
+               printf("Image does not seem to be a valid Windows CE image!\n");
+               return CMD_RET_FAILURE;
+       }
+       return CMD_RET_FAILURE; /* never reached - just to keep compiler happy */
+}
+U_BOOT_CMD(
+       bootce, 2, 0, do_bootce,
+       "Boot a Windows CE image from RAM",
+       "[addr]\n"
+       "\taddr\t\tboot image from address addr (default ${fileaddr})\n"
+       "or\n"
+       "\t-i\t\tinitialize the WinCE globals data structure (before loading a .nb0 image)"
+);
+
+#ifdef CONFIG_CMD_NAND
+static int ce_nand_load(ce_bin *bin, loff_t *offset, void *buf, size_t max_len)
+{
+       int ret;
+       size_t len = max_len;
+       nand_info_t *nand = &nand_info[0];
+
+       while (nand_block_isbad(nand, *offset & ~(max_len - 1))) {
+               printf("Skipping bad block 0x%08llx\n",
+                       *offset & ~(max_len - 1));
+               *offset += max_len;
+               if (*offset + max_len > nand->size)
+                       return -EINVAL;
+       }
+
+       ret = nand_read(nand, *offset, &len, buf);
+       if (ret < 0)
+               return ret;
+
+       bin->dataLen = len;
+       return len;
+}
+
+static int do_nbootce(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int ret;
+       struct mtd_device *dev;
+       struct part_info *part_info;
+       u8 part_num;
+       loff_t offset;
+       char *end;
+       void *buffer;
+       size_t bufsize = nand_info[0].erasesize, len;
+
+       if (argc < 2 || argc > 3)
+               return CMD_RET_USAGE;
+
+       ret = mtdparts_init();
+       if (ret)
+               return CMD_RET_FAILURE;
+
+       offset = simple_strtoul(argv[1], &end, 16);
+       if (*end != '\0') {
+               ret = find_dev_and_part(argv[1], &dev, &part_num,
+                                       &part_info);
+               if (ret != 0) {
+                       printf("Partition '%s' not found\n", argv[1]);
+                       return CMD_RET_FAILURE;
+               }
+               offset = part_info->offset;
+               printf ("## Booting Windows CE Image from NAND partition %s at offset %08llx\n",
+                       argv[1], offset);
+       } else {
+               printf ("## Booting Windows CE Image from NAND offset %08llx\n",
+                       offset);
+       }
+
+       buffer = malloc(bufsize);
+       if (buffer == NULL) {
+               printf("Failed to allocate %u byte buffer\n", bufsize);
+               return CMD_RET_FAILURE;
+       }
+
+       ce_init_bin(&g_bin, buffer);
+
+       ret = ce_nand_load(&g_bin, &offset, buffer, bufsize);
+       if (ret < 0) {
+               printf("Failed to read NAND: %d\n", ret);
+               goto err;
+       }
+       len = ret;
+       /* check if there is a valid windows CE image header */
+       if (ce_is_bin_image(buffer, len)) {
+               do {
+                       ret = ce_parse_bin(&g_bin);
+                       switch (ret) {
+                       case CE_PR_MORE:
+                       {
+                               if (ctrlc()) {
+                                       printf("NBOOTCE - canceled by user\n");
+                                       goto err;
+                               }
+                               offset += len;
+                               len = ce_nand_load(&g_bin, &offset, buffer,
+                                               bufsize);
+                               if (len < 0) {
+                                       printf("Nand read error: %d\n", len);
+                                       ret = len;
+                                       goto err;
+                               }
+                       }
+                       break;
+
+                       case CE_PR_EOF:
+                               ce_prepare_run_bin(&g_bin);
+                               break;
+
+                       case CE_PR_ERROR:
+                               break;
+                       }
+               } while (ret == CE_PR_MORE);
+               free(buffer);
+               if (ret != CE_PR_EOF)
+                       return CMD_RET_FAILURE;
+
+               if (getenv_yesno("autostart") != 1) {
+                       /*
+                        * just use bootce to load the image to SDRAM;
+                        * Do not start it automatically.
+                        */
+                       setenv_addr("fileaddr", g_bin.eEntryPoint);
+                       return CMD_RET_SUCCESS;
+               }
+               ce_run_bin(g_bin.eEntryPoint);          /* start the image */
+       } else {
+               printf("Image does not seem to be a valid Windows CE image!\n");
+       }
+err:
+       free(buffer);
+       return CMD_RET_FAILURE;
+}
+U_BOOT_CMD(
+       nbootce, 2, 0, do_nbootce,
+       "Boot a Windows CE image from NAND",
+       "off|partitition\n"
+       "\toff\t\t- flash offset (hex)\n"
+       "\tpartition\t- partition name"
+);
+#endif
+
+static int ce_send_write_ack(ce_net *net)
+{
+       int ret;
+       unsigned short wdata[2];
+       int retries = 0;
+
+       wdata[0] = htons(EDBG_CMD_WRITE_ACK);
+       wdata[1] = htons(net->blockNum);
+       net->dataLen = sizeof(wdata);
+       memcpy(net->data, wdata, net->dataLen);
+
+       do {
+               ret = bootme_send_frame(net->data, net->dataLen);
+               if (ret) {
+                       printf("Failed to send write ack %d; retries=%d\n",
+                               ret, retries);
+               }
+       } while (ret != 0 && retries-- > 0);
+       return ret;
+}
+
+static enum bootme_state ce_process_download(ce_net *net, ce_bin *bin)
+{
+       int ret = net->state;
+
+       if (net->dataLen >= 4) {
+               unsigned short command;
+               unsigned short blknum;
+
+               memcpy(&command, net->data, sizeof(command));
+               command = ntohs(command);
+               debug("command found: 0x%04X\n", command);
+
+               if (net->state == BOOTME_DOWNLOAD) {
+                       unsigned short nxt = net->blockNum + 1;
+
+                       memcpy(&blknum, &net->data[2], sizeof(blknum));
+                       blknum = ntohs(blknum);
+                       if (blknum == nxt) {
+                               net->blockNum = blknum;
+                       } else {
+                               int rc = ce_send_write_ack(net);
+
+                               if (net->verbose)
+                                       printf("Dropping out of sequence packet with ID %d (expected %d)\n",
+                                               blknum, nxt);
+                               if (rc != 0)
+                                       return rc;
+
+                               return ret;
+                       }
+               }
+
+               switch (command) {
+               case EDBG_CMD_WRITE_REQ:
+                       if (net->state == BOOTME_INIT) {
+                               // Check file name for WRITE request
+                               // CE EShell uses "boot.bin" file name
+                               if (strncmp((char *)&net->data[2],
+                                               "boot.bin", 8) == 0) {
+                                       // Some diag output
+                                       if (net->verbose) {
+                                               printf("Locked Down download link, IP: %pI4\n",
+                                                       &NetServerIP);
+                                               printf("Sending BOOTME request [%d] to %pI4\n",
+                                                       net->seqNum, &NetServerIP);
+                                       }
+
+                                       // Lock down EShell download link
+                                       ret = BOOTME_DOWNLOAD;
+                               } else {
+                                       // Unknown link
+                                       printf("Unknown link\n");
+                               }
+
+                               if (ret == BOOTME_DOWNLOAD) {
+                                       int rc = ce_send_write_ack(net);
+                                       if (rc != 0)
+                                               return rc;
+                               }
+                       }
+                       break;
+
+               case EDBG_CMD_WRITE:
+                       /* Fixup data len */
+                       bin->data = &net->data[4];
+                       bin->dataLen = net->dataLen - 4;
+                       ret = ce_parse_bin(bin);
+                       if (ret != CE_PR_ERROR) {
+                               int rc = ce_send_write_ack(net);
+                               if (rc)
+                                       return rc;
+                               if (ret == CE_PR_EOF)
+                                       ret = BOOTME_DONE;
+                       } else {
+                               ret = BOOTME_ERROR;
+                       }
+                       break;
+
+               case EDBG_CMD_READ_REQ:
+                       printf("Ignoring EDBG_CMD_READ_REQ\n");
+                       /* Read requests are not supported
+                        * Do nothing ...
+                        */
+                       break;
+
+               case EDBG_CMD_ERROR:
+                       printf("Error: unknown error on the host side\n");
+
+                       bin->binLen = 0;
+                       ret = BOOTME_ERROR;
+                       break;
+
+               default:
+                       printf("unknown command 0x%04X\n", command);
+                       net->state = BOOTME_ERROR;
+               }
+       }
+       return ret;
+}
+
+static enum bootme_state ce_process_edbg(ce_net *net, ce_bin *bin)
+{
+       enum bootme_state ret = net->state;
+       eth_dbg_hdr header;
+
+       if (net->dataLen < sizeof(header)) {
+               /* Bad packet */
+               printf("Invalid packet size %u\n", net->dataLen);
+               net->dataLen = 0;
+               return ret;
+       }
+       memcpy(&header, net->data, sizeof(header));
+       if (header.id != EDBG_ID) {
+               /* Bad packet */
+               printf("Bad EDBG ID %08x\n", header.id);
+               net->dataLen = 0;
+               return ret;
+       }
+
+       if (header.service != EDBG_SVC_ADMIN) {
+               /* Unknown service */
+               printf("Bad EDBG service %02x\n", header.service);
+               net->dataLen = 0;
+               return ret;
+       }
+
+       if (net->state == BOOTME_INIT) {
+               /* Some diag output */
+               if (net->verbose) {
+                       printf("Locked Down EDBG service link, IP: %pI4\n",
+                               &NetServerIP);
+               }
+
+               /* Lock down EDBG link */
+               net->state = BOOTME_DEBUG;
+       }
+
+       switch (header.cmd) {
+       case EDBG_CMD_JUMPIMG:
+               net->gotJumpingRequest = 1;
+
+               if (net->verbose) {
+                       printf("Received JUMPING command\n");
+               }
+               /* Just pass through and copy CONFIG structure */
+               ret = BOOTME_DONE;
+       case EDBG_CMD_OS_CONFIG:
+               /* Copy config structure */
+               memcpy(&bin->edbgConfig, &net->data[sizeof(header)],
+                       sizeof(edbg_os_config_data));
+               if (net->verbose) {
+                       printf("Received CONFIG command\n");
+                       if (bin->edbgConfig.flags & EDBG_FL_DBGMSG) {
+                               printf("--> Enabling DBGMSG service, IP: %pI4, port: %d\n",
+                                       &bin->edbgConfig.dbgMsgIPAddr,
+                                       ntohs(bin->edbgConfig.dbgMsgPort));
+                       }
+
+                       if (bin->edbgConfig.flags & EDBG_FL_PPSH) {
+                               printf("--> Enabling PPSH service, IP: %pI4, port: %d\n",
+                                       &bin->edbgConfig.ppshIPAddr,
+                                       ntohs(bin->edbgConfig.ppshPort));
+                       }
+
+                       if (bin->edbgConfig.flags & EDBG_FL_KDBG) {
+                               printf("--> Enabling KDBG service, IP: %pI4, port: %d\n",
+                                       &bin->edbgConfig.kdbgIPAddr,
+                                       ntohs(bin->edbgConfig.kdbgPort));
+                       }
+
+                       if (bin->edbgConfig.flags & EDBG_FL_CLEANBOOT) {
+                               printf("--> Force clean boot\n");
+                       }
+               }
+               break;
+
+       default:
+               if (net->verbose) {
+                       printf("Received unknown command: %08X\n", header.cmd);
+               }
+               return BOOTME_ERROR;
+       }
+
+       /* Respond with ack */
+       header.flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
+       memcpy(net->data, &header, sizeof(header));
+       net->dataLen = EDBG_DATA_OFFSET;
+
+       int retries = 10;
+       int rc;
+       do {
+               rc = bootme_send_frame(net->data, net->dataLen);
+               if (rc != 0) {
+                       printf("Failed to send ACK: %d\n", rc);
+               }
+       } while (rc && retries-- > 0);
+       return rc ?: ret;
+}
+
+static enum bootme_state ce_edbg_handler(const void *buf, size_t len)
+{
+       if (len == 0)
+               return BOOTME_DONE;
+
+       g_net.data = (void *)buf;
+       g_net.dataLen = len;
+
+       return ce_process_edbg(&g_net, &g_bin);
+}
+
+static void ce_init_edbg_link(ce_net *net)
+{
+       /* Initialize EDBG link for commands */
+       net->state = BOOTME_INIT;
+}
+
+static enum bootme_state ce_download_handler(const void *buf, size_t len)
+{
+       g_net.data = (void *)buf;
+       g_net.dataLen = len;
+
+       g_net.state = ce_process_download(&g_net, &g_bin);
+       return g_net.state;
+}
+
+static int ce_send_bootme(ce_net *net)
+{
+       eth_dbg_hdr *header;
+       edbg_bootme_data *data;
+       unsigned char txbuf[PKTSIZE_ALIGN];
+#ifdef DEBUG
+       int     i;
+       unsigned char   *pkt;
+#endif
+       /* Fill out BOOTME packet */
+       net->data = txbuf;
+
+       memset(net->data, 0, PKTSIZE);
+       header = (eth_dbg_hdr *)net->data;
+       data = (edbg_bootme_data *)header->data;
+
+       header->id = EDBG_ID;
+       header->service = EDBG_SVC_ADMIN;
+       header->flags = EDBG_FL_FROM_DEV;
+       header->seqNum = net->seqNum++;
+       header->cmd = EDBG_CMD_BOOTME;
+
+       data->versionMajor = 0;
+       data->versionMinor = 0;
+       data->cpuId = EDBG_CPU_TYPE_ARM;
+       data->bootmeVer = EDBG_CURRENT_BOOTME_VERSION;
+       data->bootFlags = 0;
+       data->downloadPort = 0;
+       data->svcPort = 0;
+
+       /* MAC address from environment*/
+       if (!eth_getenv_enetaddr("ethaddr", data->macAddr)) {
+               printf("'ethaddr' is not set or invalid\n");
+               memset(data->macAddr, 0, sizeof(data->macAddr));
+       }
+
+       /* IP address from active config */
+       NetCopyIP(&data->ipAddr, &NetOurIP);
+
+       // Device name string (NULL terminated). Should include
+       // platform and number based on Ether address (e.g. Odo42, CEPCLS2346, etc)
+
+       // We will use lower MAC address segment to create device name
+       // eg. MAC '00-0C-C6-69-09-05', device name 'Triton05'
+
+       strncpy(data->platformId, "Triton", sizeof(data->platformId));
+       snprintf(data->deviceName, sizeof(data->deviceName), "%s%02X",
+               data->platformId, data->macAddr[5]);
+
+#ifdef DEBUG
+       printf("header->id: %08X\n", header->id);
+       printf("header->service: %08X\n", header->service);
+       printf("header->flags: %08X\n", header->flags);
+       printf("header->seqNum: %08X\n", header->seqNum);
+       printf("header->cmd: %08X\n\n", header->cmd);
+
+       printf("data->versionMajor: %08X\n", data->versionMajor);
+       printf("data->versionMinor: %08X\n", data->versionMinor);
+       printf("data->cpuId: %08X\n", data->cpuId);
+       printf("data->bootmeVer: %08X\n", data->bootmeVer);
+       printf("data->bootFlags: %08X\n", data->bootFlags);
+       printf("data->svcPort: %08X\n\n", ntohs(data->svcPort));
+
+       printf("data->macAddr: %pM\n", data->macAddr);
+       printf("data->ipAddr: %pI4\n", &data->ipAddr);
+       printf("data->platformId: %s\n", data->platformId);
+       printf("data->deviceName: %s\n", data->deviceName);
+#endif
+       // Some diag output ...
+       if (net->verbose) {
+               printf("Sending BOOTME request [%d] to %pI4\n", net->seqNum,
+                       &server_ip);
+       }
+
+       net->dataLen = BOOTME_PKT_SIZE;
+//     net->status = CE_PR_MORE;
+       net->state = BOOTME_INIT;
+#ifdef DEBUG
+       debug("Start of buffer:      %p\n", net->data);
+       debug("Start of ethernet buffer:   %p\n", net->data);
+       debug("Start of CE header:         %p\n", header);
+       debug("Start of CE data:           %p\n", data);
+
+       pkt = net->data;
+       debug("packet to send (ceconnect): \n");
+       for (i = 0; i < net->dataLen; i++) {
+               debug("0x%02X ", pkt[i]);
+               if (!((i + 1) % 16))
+                       debug("\n");
+       }
+       debug("\n");
+#endif
+       return BootMeRequest(server_ip, net->data, net->dataLen, 1);
+}
+
+static inline int ce_init_download_link(ce_net *net, ce_bin *bin, int verbose)
+{
+       if (!eth_get_dev()) {
+               printf("No network interface available\n");
+               return -ENODEV;
+       }
+       printf("Using device '%s'\n", eth_get_name());
+
+       /* Initialize EDBG link for download */
+       memset(net, 0, sizeof(*net));
+
+       net->verbose = verbose;
+
+       /* buffer will be dynamically assigned in ce_download_handler() */
+       ce_init_bin(bin, NULL);
+       return 0;
+}
+
+static inline int ce_download_file(ce_net *net, ulong timeout)
+{
+       ulong start = get_timer_masked();
+
+       while (net->state == BOOTME_INIT) {
+               int ret;
+
+               if (timeout && get_timer(start) > timeout) {
+                       printf("CELOAD - Canceled, timeout\n");
+                       return 1;
+               }
+
+               if (ctrlc()) {
+                       printf("CELOAD - canceled by user\n");
+                       return 1;
+               }
+
+               if (ce_send_bootme(&g_net)) {
+                       printf("CELOAD - error while sending BOOTME request\n");
+                       return 1;
+               }
+               if (net->verbose) {
+                       if (timeout) {
+                               printf("Waiting for connection, timeout %lu sec\n",
+                                       DIV_ROUND_UP(timeout - get_timer(start),
+                                               CONFIG_SYS_HZ));
+                       } else {
+                               printf("Waiting for connection, enter ^C to abort\n");
+                       }
+               }
+
+               ret = BootMeDownload(ce_download_handler);
+               if (ret == BOOTME_ERROR) {
+                       printf("CELOAD - aborted\n");
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static void ce_disconnect(void)
+{
+       net_set_udp_handler(NULL);
+       eth_halt();
+}
+
+static int do_ceconnect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int verbose = 0;
+       ulong timeout = 0;
+       int ret = 1;
+       int i;
+
+       server_ip = 0;
+
+       for (i = 1; i < argc; i++){
+               if (*argv[i] != '-')
+                       break;
+               if (argv[i][1] == 'v') {
+                       verbose = 1;
+               } else if (argv[i][1] == 't') {
+                       i++;
+                       if (argc > i) {
+                               timeout = simple_strtoul(argv[i],
+                                                       NULL, 0);
+                               if (timeout >= UINT_MAX / CONFIG_SYS_HZ) {
+                                       printf("Timeout value %lu out of range (max.: %u)\n",
+                                               timeout, UINT_MAX / CONFIG_SYS_HZ - 1);
+                                       return CMD_RET_USAGE;
+                               }
+                               timeout *= CONFIG_SYS_HZ;
+                       } else {
+                               printf("Option requires an argument - t\n");
+                               return CMD_RET_USAGE;
+                       }
+               } else if (argv[i][1] == 'h') {
+                       i++;
+                       if (argc > i) {
+                               server_ip = string_to_ip(argv[i]);
+                               printf("Using server %pI4\n", &server_ip);
+                       } else {
+                               printf("Option requires an argument - h\n");
+                               return CMD_RET_USAGE;
+                       }
+               }
+       }
+
+       if (ce_init_download_link(&g_net, &g_bin, verbose) != 0)
+               goto err;
+
+       if (ce_download_file(&g_net, timeout))
+               goto err;
+
+       if (g_bin.binLen) {
+               // Try to receive edbg commands from host
+               ce_init_edbg_link(&g_net);
+               if (verbose)
+                       printf("Waiting for EDBG commands ...\n");
+
+               ret = BootMeDebugStart(ce_edbg_handler);
+               if (ret != BOOTME_DONE)
+                       goto err;
+
+               // Prepare WinCE image for execution
+               ce_prepare_run_bin(&g_bin);
+
+               // Launch WinCE, if necessary
+               if (g_net.gotJumpingRequest)
+                       ce_run_bin(g_bin.eEntryPoint);
+       }
+       ret = 0;
+err:
+       ce_disconnect();
+       return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
+}
+U_BOOT_CMD(
+       ceconnect, 6, 1, do_ceconnect,
+       "Set up a connection to the CE host PC over TCP/IP and download the run-time image",
+       "[-v] [-t <timeout>] [-h host]\n"
+       "  -v            - verbose operation\n"
+       "  -t <timeout>  - max wait time (#sec) for the connection\n"
+       "  -h <host>     - send BOOTME requests to <host> (default: broadcast address 255.255.255.255)"
+);
index e38422d792eec2784102bccadea93b5b522c8666..446da2c97009a8ab682ad5726204a7d785dfa846 100644 (file)
@@ -141,6 +141,7 @@ static int set_gpt_info(block_dev_desc_t *dev_desc,
        char *val, *p;
        int p_count;
        disk_partition_t *parts;
+       char *guid_str;
        int errno = 0;
        uint64_t size_ll, start_ll;
 
@@ -157,16 +158,20 @@ static int set_gpt_info(block_dev_desc_t *dev_desc,
        tok = strsep(&s, ";");
        val = extract_val(tok, "uuid_disk");
        if (!val) {
-               free(str);
-               return -2;
+               errno = -2;
+               goto free_str;
        }
-       if (extract_env(val, &p))
-               p = val;
-       *str_disk_guid = strdup(p);
+       if (extract_env(val, &p) == 0)
+               guid_str = strdup(p);
+       else
+               guid_str = strdup(val);
+
        free(val);
 
-       if (strlen(s) == 0)
-               return -3;
+       if (strlen(s) == 0) {
+               errno = -3;
+               goto free_guid;
+       }
 
        i = strlen(s) - 1;
        if (s[i] == ';')
@@ -244,16 +249,23 @@ static int set_gpt_info(block_dev_desc_t *dev_desc,
                }
        }
 
+       *str_disk_guid = guid_str;
        *parts_count = p_count;
        *partitions = parts;
        free(str);
 
        return 0;
+
 err:
-       free(str);
-       free(*str_disk_guid);
        free(parts);
+free_guid:
+       free(guid_str);
+free_str:
+       free(str);
 
+       *str_disk_guid = NULL;
+       *parts_count = 0;
+       *partitions = NULL;
        return errno;
 }
 
index 4e28c9d7a4d6541f0c1633ee494b77e476b5e776..c89782ab4bd4bc8abf95d823b4e02a787a2f7cb7 100644 (file)
@@ -32,7 +32,7 @@ int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
                if (mmc_legacy_init(dev) != 0) {
                        puts("No MMC card found\n");
-                       return 1;
+                       return CMD_RET_FAILURE;
                }
 
                curr_device = dev;
@@ -41,14 +41,14 @@ int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                if (argc == 2) {
                        if (curr_device < 0) {
                                puts("No MMC device available\n");
-                               return 1;
+                               return CMD_RET_FAILURE;
                        }
                } else if (argc == 3) {
                        dev = (int)simple_strtoul(argv[2], NULL, 10);
 
 #ifdef CONFIG_SYS_MMC_SET_DEV
                        if (mmc_set_dev(dev) != 0)
-                               return 1;
+                               return CMD_RET_FAILURE;
 #endif
                        curr_device = dev;
                } else {
@@ -60,7 +60,7 @@ int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                return CMD_RET_USAGE;
        }
 
-       return 0;
+       return CMD_RET_SUCCESS;
 }
 
 U_BOOT_CMD(
@@ -160,7 +160,7 @@ static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        curr_device = 0;
                else {
                        puts("No MMC device available\n");
-                       return 1;
+                       return CMD_RET_FAILURE;
                }
        }
 
index 422c069513843f930ce1eeccf2a9aa2e89b7fcf1..3e34558acfd1a38ec4527e2618cf9db9ea7271fd 100644 (file)
@@ -325,8 +325,7 @@ static int part_validate_eraseblock(struct mtdids *id, struct part_info *part)
                 */
                offset = part->offset;
                if (do_div(offset, mtd->erasesize)) {
-                       printf("%s%d: partition (%s) start offset"
-                              "alignment incorrect\n",
+                       printf("%s%d: partition (%s) start offset alignment incorrect\n",
                               MTD_DEV_TYPE(id->type), id->num, part->name);
                        return 1;
                }
index 7f962dcb25a080f892fde9d6b79934d9f428f6fd..7d477aac56f93c62119bf95d7f5789de85f0930c 100644 (file)
@@ -489,7 +489,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        /* Only "dump" is repeatable. */
        if (repeat && strcmp(cmd, "dump"))
-               return 0;
+               return CMD_RET_FAILURE;
 
        if (strcmp(cmd, "info") == 0) {
 
@@ -498,7 +498,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        if (nand_info[i].name)
                                nand_print_and_set_info(i);
                }
-               return 0;
+               return CMD_RET_SUCCESS;
        }
 
        if (strcmp(cmd, "device") == 0) {
@@ -508,19 +508,20 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                                puts("no devices available\n");
                        else
                                nand_print_and_set_info(dev);
-                       return 0;
+                       return CMD_RET_SUCCESS;
                }
 
                dev = (int)simple_strtoul(argv[2], NULL, 10);
                set_dev(dev);
 
-               return 0;
+               return CMD_RET_SUCCESS;
        }
 
 #ifdef CONFIG_ENV_OFFSET_OOB
        /* this command operates only on the first nand device */
        if (strcmp(cmd, "env.oob") == 0)
-               return do_nand_env_oob(cmdtp, argc - 1, argv + 1);
+               return do_nand_env_oob(cmdtp, argc - 1, argv + 1) ?
+                       CMD_RET_FAILURE : CMD_RET_SUCCESS;;
 #endif
 
        /* The following commands operate on the current device, unless
@@ -532,7 +533,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        if (dev < 0 || dev >= CONFIG_SYS_MAX_NAND_DEVICE ||
            !nand_info[dev].name) {
                puts("\nno devices available\n");
-               return 1;
+               return CMD_RET_FAILURE;
        }
        nand = &nand_info[dev];
 
@@ -541,7 +542,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                for (off = 0; off < nand->size; off += nand->erasesize)
                        if (nand_block_isbad(nand, off))
                                printf("  %08llx\n", (unsigned long long)off);
-               return 0;
+               return CMD_RET_SUCCESS;
        }
 
        /*
@@ -593,7 +594,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                /* skip first two or three arguments, look for offset and size */
                if (arg_off_size(argc - o, argv + o, &dev, &off, &size,
                                 &maxsize) != 0)
-                       return 1;
+                       return CMD_RET_FAILURE;
 
                nand = &nand_info[dev];
 
@@ -613,14 +614,14 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                                        opts.scrub = 1;
                                } else {
                                        puts("scrub aborted\n");
-                                       return 1;
+                                       return CMD_RET_FAILURE;
                                }
                        }
                }
                ret = nand_erase_opts(nand, &opts);
                printf("%s\n", ret ? "ERROR" : "OK");
 
-               return ret == 0 ? 0 : 1;
+               return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
        }
 
        if (strncmp(cmd, "dump", 4) == 0) {
@@ -630,7 +631,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                off = (int)simple_strtoul(argv[2], NULL, 16);
                ret = nand_dump(nand, off, !strcmp(&cmd[4], ".oob"), repeat);
 
-               return ret == 0 ? 1 : 0;
+               return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
        }
 
        if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) {
@@ -695,7 +696,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                } else if (!strcmp(s, ".trimffs")) {
                        if (read) {
                                printf("Unknown nand command suffix '%s'\n", s);
-                               return 1;
+                               return CMD_RET_FAILURE;
                        }
                        ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
                                                maxsize, (u_char *)addr,
@@ -705,7 +706,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                } else if (!strcmp(s, ".yaffs")) {
                        if (read) {
                                printf("Unknown nand command suffix '%s'.\n", s);
-                               return 1;
+                               return CMD_RET_FAILURE;
                        }
                        ret = nand_write_skip_bad(nand, off, &rwsize, NULL,
                                                maxsize, (u_char *)addr,
@@ -727,13 +728,13 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        ret = raw_access(nand, addr, off, pagecount, read);
                } else {
                        printf("Unknown nand command suffix '%s'.\n", s);
-                       return 1;
+                       return CMD_RET_FAILURE;
                }
 
                printf(" %zu bytes %s: %s\n", rwsize,
                       read ? "read" : "written", ret ? "ERROR" : "OK");
 
-               return ret == 0 ? 0 : 1;
+               return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
        }
 
 #ifdef CONFIG_CMD_NAND_TORTURE
@@ -778,12 +779,12 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        --argc;
                        ++argv;
                }
-               return ret;
+               return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
        }
 
        if (strcmp(cmd, "biterr") == 0) {
                /* todo */
-               return 1;
+               return CMD_RET_FAILURE;
        }
 
 #ifdef CONFIG_CMD_NAND_LOCK_UNLOCK
@@ -803,10 +804,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                                puts("NAND flash successfully locked\n");
                        } else {
                                puts("Error locking NAND flash\n");
-                               return 1;
+                               return CMD_RET_FAILURE;
                        }
                }
-               return 0;
+               return CMD_RET_SUCCESS;
        }
 
        if (strncmp(cmd, "unlock", 5) == 0) {
@@ -819,16 +820,16 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
                if (arg_off_size(argc - 2, argv + 2, &dev, &off, &size,
                                 &maxsize) < 0)
-                       return 1;
+                       return CMD_RET_FAILURE;
 
                if (!nand_unlock(&nand_info[dev], off, size, allexcept)) {
                        puts("NAND flash successfully unlocked\n");
                } else {
                        puts("Error unlocking NAND flash, "
                             "write and erase will probably fail\n");
-                       return 1;
+                       return CMD_RET_FAILURE;
                }
-               return 0;
+               return CMD_RET_SUCCESS;
        }
 #endif
 
index 9c9bb82c0faf81f3d6d6295f99ecfcfd3a1cea2b..dc457f959d708e98cba41b8714d340748f687c4d 100644 (file)
@@ -44,8 +44,6 @@ char *env_name_spec = "NAND";
 env_t *env_ptr = &environment;
 #elif defined(CONFIG_NAND_ENV_DST)
 env_t *env_ptr = (env_t *)CONFIG_NAND_ENV_DST;
-#else /* ! ENV_IS_EMBEDDED */
-env_t *env_ptr;
 #endif /* ENV_IS_EMBEDDED */
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -350,7 +348,9 @@ void env_relocate_spec(void)
                        gd->env_valid = 1;
        }
 
+#ifdef CONFIG_NAND_ENV_DST
        free(env_ptr);
+#endif
 
        if (gd->env_valid == 1)
                ep = tmp_env1;
index 8266bca7d6489a2ca8fb6f1015064184b137d2dd..897ace6295bf831e10bbe7c52820c43f105d6e15 100644 (file)
@@ -532,7 +532,8 @@ int fdt_shrink_to_minimum(void *blob)
        ret = fdt_add_mem_rsv(blob, (uintptr_t)blob, actualsize);
        if (ret < 0)
                return ret;
-
+       if (getenv("fdtsize"))
+               setenv_hex("fdtsize", actualsize);
        return actualsize;
 }
 
@@ -1085,7 +1086,7 @@ static u64 __of_translate_address(void *blob, int node_offset, const fdt32_t *in
                goto bail;
        bus = &of_busses[0];
 
-       /* Cound address cells & copy address locally */
+       /* Count address cells & copy address locally */
        bus->count_cells(blob, parent, &na, &ns);
        if (!OF_CHECK_COUNTS(na, ns)) {
                printf("%s: Bad cell count for %s\n", __FUNCTION__,
index 1195a54efcc742837f3cb703b4c8ad6f5d356569..41af1b199b3ba3955a8b6897463ace2e66c3bb02 100644 (file)
@@ -60,7 +60,7 @@
 #ifdef CONFIG_LCD_LOGO
 # include <bmp_logo.h>         /* Get logo data, width and height      */
 # include <bmp_logo_data.h>
-# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP != LCD_COLOR16)
+# if (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET) && (LCD_BPP < LCD_COLOR16)
 #  error Default Color Map overlaps with Logo Color Map
 # endif
 #endif
@@ -153,6 +153,16 @@ static int test_colors[N_BLK_HOR * N_BLK_VERT] = {
        CONSOLE_COLOR_BLUE,     CONSOLE_COLOR_MAGENTA,  CONSOLE_COLOR_CYAN,
 };
 
+#if LCD_BPP == LCD_COLOR8
+typedef uchar pix_t;
+#elif LCD_BPP == LCD_COLOR16
+typedef ushort pix_t;
+#elif LCD_BPP == LCD_COLOR32
+typedef ulong pix_t;
+#else
+#error Unsupported pixelformat
+#endif
+
 static void test_pattern(void)
 {
        ushort v_max  = panel_info.vl_row;
@@ -160,7 +170,7 @@ static void test_pattern(void)
        ushort v_step = (v_max + N_BLK_VERT - 1) / N_BLK_VERT;
        ushort h_step = (h_max + N_BLK_HOR  - 1) / N_BLK_HOR;
        ushort v, h;
-       uchar *pix = (uchar *)lcd_base;
+       pix_t *pix = lcd_base;
 
        printf("[LCD] Test Pattern: %d x %d [%d x %d]\n",
                h_max, v_max, h_step, v_step);
@@ -260,7 +270,7 @@ void lcd_clear(void)
 #endif
 #endif
        /* Paint the logo and retrieve LCD base address */
-       debug("[LCD] Drawing the logo...\n");
+       debug("[LCD] Drawing the logo @ %p...\n", lcd_base);
 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
        console_rows = (panel_info.vl_row - BMP_LOGO_HEIGHT);
        console_rows /= VIDEO_FONT_HEIGHT;
@@ -291,7 +301,9 @@ U_BOOT_CMD(
 static int lcd_init(void *lcdbase)
 {
        /* Initialize the lcd controller */
-       debug("[LCD] Initializing LCD frambuffer at %p\n", lcdbase);
+       debug("[LCD] Initializing %ux%ux%u LCD framebuffer at %p\n",
+               panel_info.vl_col, panel_info.vl_row, NBITS(panel_info.vl_bpix),
+               lcdbase);
 
        lcd_ctrl_init(lcdbase);
 
@@ -389,7 +401,7 @@ static inline ushort *configuration_get_cmap(void)
        struct pxafb_info *fbi = &panel_info.pxa;
        return (ushort *)fbi->palette;
 #elif defined(CONFIG_MPC823)
-       immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+       immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
        cpm8xx_t *cp = &(immr->im_cpm);
        return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]);
 #elif defined(CONFIG_ATMEL_LCD)
@@ -416,7 +428,7 @@ void bitmap_plot(int x, int y)
        uchar *fb;
        ushort *fb16;
 #if defined(CONFIG_MPC823)
-       immap_t *immr = (immap_t *) CONFIG_SYS_IMMR;
+       immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
        cpm8xx_t *cp = &(immr->im_cpm);
 #endif
        unsigned bpix = NBITS(panel_info.vl_bpix);
@@ -472,8 +484,7 @@ void bitmap_plot(int x, int y)
                        bmap += BMP_LOGO_WIDTH;
                        fb += panel_info.vl_col;
                }
-       }
-       else { /* true color mode */
+       } else if (NBITS(panel_info.vl_bpix) == 16) {
                u16 col16;
                fb16 = (ushort *)fb;
                for (i = 0; i < BMP_LOGO_HEIGHT; ++i) {
@@ -487,6 +498,21 @@ void bitmap_plot(int x, int y)
                        bmap += BMP_LOGO_WIDTH;
                        fb16 += panel_info.vl_col;
                }
+       } else { /* true color mode */
+               u16 col16;
+               u32 *fb32 = lcd_base + y * lcd_line_length + x;
+
+               for (i = 0; i < BMP_LOGO_HEIGHT; i++) {
+                       for (j = 0; j < BMP_LOGO_WIDTH; j++) {
+                               col16 = bmp_logo_palette[bmap[j] - 16];
+                               fb32[j] =
+                                       ((col16 & 0x000F) << 4) |
+                                       ((col16 & 0x00F0) << 8) |
+                                       ((col16 & 0x0F00) << 12);
+                               }
+                       bmap += BMP_LOGO_WIDTH;
+                       fb32 += panel_info.vl_col;
+               }
        }
 
        WATCHDOG_RESET();
@@ -677,6 +703,12 @@ static inline void fb_put_word(uchar **fb, uchar **from)
 #endif
 #endif /* CONFIG_BMP_16BPP */
 
+static inline bmp_color_table_entry_t *get_color_table(bmp_image_t *bmp)
+{
+       bmp_header_t *bh = &bmp->header;
+       return (void *)bmp + offsetof(bmp_header_t, size) + bh->size;
+}
+
 int lcd_display_bitmap(ulong bmp_image, int x, int y)
 {
        ushort *cmap = NULL;
@@ -686,9 +718,11 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
        bmp_image_t *bmp = (bmp_image_t *)map_sysmem(bmp_image, 0);
        uchar *bmap;
        ushort padded_width;
-       unsigned long width, height, byte_width;
+       unsigned long width, height;
        unsigned long pwidth = panel_info.vl_col;
-       unsigned colors, bpix, bmp_bpix;
+       unsigned long long colors;
+       unsigned bpix, bmp_bpix;
+       bmp_color_table_entry_t *cte;
 
        if (!bmp || !(bmp->header.signature[0] == 'B' &&
                bmp->header.signature[1] == 'M')) {
@@ -724,21 +758,21 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                return 1;
        }
 
-       debug("Display-bmp: %d x %d  with %d colors\n",
-               (int)width, (int)height, (int)colors);
+       debug("Display-bmp: %lu x %lu  with %llu colors\n",
+               width, height, colors);
 
+       cte = get_color_table(bmp);
        if (bmp_bpix == 8) {
                cmap = configuration_get_cmap();
                cmap_base = cmap;
 
                /* Set color map */
                for (i = 0; i < colors; ++i) {
-                       bmp_color_table_entry_t cte = bmp->color_table[i];
 #if !defined(CONFIG_ATMEL_LCD)
                        ushort colreg =
-                               ( ((cte.red)   << 8) & 0xf800) |
-                               ( ((cte.green) << 3) & 0x07e0) |
-                               ( ((cte.blue)  >> 3) & 0x001f) ;
+                               ( ((cte[i].red)   << 8) & 0xf800) |
+                               ( ((cte[i].green) << 3) & 0x07e0) |
+                               ( ((cte[i].blue)  >> 3) & 0x001f) ;
                        *cmap = colreg;
 #if defined(CONFIG_MPC823)
                        cmap--;
@@ -746,24 +780,26 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                        cmap++;
 #endif
 #else /* CONFIG_ATMEL_LCD */
-                       lcd_setcolreg(i, cte.red, cte.green, cte.blue);
+                       lcd_setcolreg(i, cte[i].red, cte[i].green, cte[i].blue);
 #endif
                }
        }
 
-       padded_width = (width & 0x3 ? (width & ~0x3) + 4 : width);
+       padded_width = ALIGN(width, 4);
 
 #ifdef CONFIG_SPLASH_SCREEN_ALIGN
        splash_align_axis(&x, pwidth, width);
        splash_align_axis(&y, panel_info.vl_row, height);
 #endif /* CONFIG_SPLASH_SCREEN_ALIGN */
+       bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
 
        if ((x + width) > pwidth)
                width = pwidth - x;
-       if ((y + height) > panel_info.vl_row)
+       if ((y + height) > panel_info.vl_row) {
                height = panel_info.vl_row - y;
+               bmap += (panel_info.vl_row - y) * padded_width;
+       }
 
-       bmap = (uchar *)bmp + get_unaligned_le32(&bmp->header.data_offset);
        fb   = (uchar *)(lcd_base +
                (y + height - 1) * lcd_line_length + x * bpix / 8);
 
@@ -783,23 +819,31 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                }
 #endif
 
-               if (bpix != 16)
-                       byte_width = width;
-               else
-                       byte_width = width * 2;
-
                for (i = 0; i < height; ++i) {
                        WATCHDOG_RESET();
                        for (j = 0; j < width; j++) {
-                               if (bpix != 16) {
-                                       FB_PUT_BYTE(fb, bmap);
-                               } else {
+                               if (bpix == 32) {
+                                       int i = *bmap++;
+
+                                       fb[3] = 0; /* T */
+                                       fb[0] = cte[i].blue;
+                                       fb[1] = cte[i].green;
+                                       fb[2] = cte[i].red;
+                                       fb += sizeof(uint32_t) / sizeof(*fb);
+                               } else if (bpix == 16) {
                                        *(uint16_t *)fb = cmap_base[*(bmap++)];
                                        fb += sizeof(uint16_t) / sizeof(*fb);
+                               } else {
+                                       FB_PUT_BYTE(fb, bmap);
                                }
                        }
-                       bmap += (padded_width - width);
-                       fb -= byte_width + lcd_line_length;
+                       if (bpix > 8) {
+                               bmap += padded_width - width;
+                               fb   -= width * bpix / 8 + lcd_line_length;
+                       } else {
+                               bmap += padded_width;
+                               fb -= lcd_line_length;
+                       }
                }
                break;
        }
@@ -827,25 +871,25 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                        fb -= lcd_line_length + width * (bpix / 8);
                }
                break;
-#endif /* CONFIG_BMP_24BMP */
+#endif /* CONFIG_BMP_24BPP */
 #if defined(CONFIG_BMP_32BPP)
        case 32:
                for (i = 0; i < height; ++i) {
+                       WATCHDOG_RESET();
                        for (j = 0; j < width; j++) {
-                               *(fb++) = *(bmap++);
-                               *(fb++) = *(bmap++);
-                               *(fb++) = *(bmap++);
-                               *(fb++) = *(bmap++);
+                               fb[3] = *bmap++; /* T */
+                               fb[0] = *bmap++; /* B */
+                               fb[1] = *bmap++; /* G */
+                               fb[2] = *bmap++; /* R */
+                               fb += 4;
                        }
+                       bmap += (padded_width - width) * 4;
                        fb -= lcd_line_length + width * (bpix / 8);
                }
                break;
 #endif /* CONFIG_BMP_32BPP */
-       default:
-               break;
        };
 
-       lcd_sync();
        return 0;
 }
 #endif
@@ -859,12 +903,16 @@ static void *lcd_logo(void)
 
        if (do_splash && (s = getenv("splashimage")) != NULL) {
                int x = 0, y = 0;
+               char *end;
+
                do_splash = 0;
 
                if (splash_screen_prepare())
                        return (void *)lcd_base;
 
-               addr = simple_strtoul (s, NULL, 16);
+               addr = simple_strtoul (s, &end, 16);
+               if (addr == 0 || *end != '\0')
+                       return lcd_base;
 
                splash_get_pos(&x, &y);
 
@@ -882,10 +930,10 @@ static void *lcd_logo(void)
 #endif /* CONFIG_LCD_INFO */
 
 #if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
-       return (void *)((ulong)lcd_base + BMP_LOGO_HEIGHT * lcd_line_length);
+       return lcd_base + BMP_LOGO_HEIGHT * lcd_line_length;
 #else
-       return (void *)lcd_base;
-#endif /* CONFIG_LCD_LOGO && !defined(CONFIG_LCD_INFO_BELOW_LOGO) */
+       return lcd_base;
+#endif /* CONFIG_LCD_LOGO && !CONFIG_LCD_INFO_BELOW_LOGO */
 }
 
 #ifdef CONFIG_SPLASHIMAGE_GUARD
index daaeb507c467b14cf0f80ecaab46e48064e58672..526bd1a754490c5f93cdd9f0d6786c1b7828dbb2 100644 (file)
@@ -182,8 +182,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
 #endif
 #ifdef CONFIG_SPL_NAND_SUPPORT
        case BOOT_DEVICE_NAND:
-               spl_nand_load_image();
-               break;
+               if (spl_nand_load_image() == 0)
+                       break;
+               /* fallthru in case of failure to activate ymodem download */
 #endif
 #ifdef CONFIG_SPL_ONENAND_SUPPORT
        case BOOT_DEVICE_ONENAND:
index b7801cb4605f16c54c99f65e3e8ed93db5d3e564..f58c21a7d646a440add27647608fa0be6df123ae 100644 (file)
 #include <nand.h>
 
 #if defined(CONFIG_SPL_NAND_RAW_ONLY)
-void spl_nand_load_image(void)
+int spl_nand_load_image(void)
 {
+       int ret;
+
        nand_init();
 
-       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+       ret = nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
                            CONFIG_SYS_NAND_U_BOOT_SIZE,
                            (void *)CONFIG_SYS_NAND_U_BOOT_DST);
-       spl_set_header_raw_uboot();
        nand_deselect();
+       if (ret)
+               return ret;
+
+       spl_set_header_raw_uboot();
+       return 0;
 }
 #else
-void spl_nand_load_image(void)
+int spl_nand_load_image(void)
 {
+       int ret;
        struct image_header *header;
        int *src __attribute__((unused));
        int *dst __attribute__((unused));
@@ -32,7 +39,7 @@ void spl_nand_load_image(void)
        nand_init();
 
        /*use CONFIG_SYS_TEXT_BASE as temporary storage area */
-       header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+       header = (struct image_header *)CONFIG_SYS_TEXT_BASE;
 #ifdef CONFIG_SPL_OS_BOOT
        if (!spl_start_uboot()) {
                /*
@@ -63,12 +70,12 @@ void spl_nand_load_image(void)
                        nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
                                spl_image.size, (void *)spl_image.load_addr);
                        nand_deselect();
-                       return;
+                       return 0;
                } else {
-                       puts("The Expected Linux image was not "
-                               "found. Please check your NAND "
+                       printf("The Expected Linux image was not"
+                               "found. Please check your NAND"
                                "configuration.\n");
-                       puts("Trying to start u-boot now...\n");
+                       printf("Trying to start u-boot now...\n");
                }
        }
 #endif
@@ -87,11 +94,14 @@ void spl_nand_load_image(void)
 #endif
 #endif
        /* Load u-boot */
-       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-               sizeof(*header), (void *)header);
-       spl_parse_image_header(header);
-       nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-               spl_image.size, (void *)spl_image.load_addr);
+       ret = nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+                               CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+       if (ret == 0) {
+               spl_parse_image_header(header);
+               ret = nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+                                       spl_image.size, (void *)spl_image.load_addr);
+       }
        nand_deselect();
+       return ret;
 }
 #endif
index 0f1e9970798b830f0d5a51c58c7c1860755732fb..10e69427df08117bf4ac5f28eaf2f2961afefce9 100644 (file)
@@ -12,6 +12,7 @@
 #include <common.h>
 #include <spl.h>
 #include <xyzModem.h>
+#include <watchdog.h>
 #include <asm/u-boot.h>
 #include <asm/utils.h>
 
@@ -34,22 +35,23 @@ void spl_ymodem_load_image(void)
        ulong store_addr = ~0;
        ulong addr = 0;
 
+loop:
        info.mode = xyzModem_ymodem;
        ret = xyzModem_stream_open(&info, &err);
-
-       if (!ret) {
-               while ((res =
-                       xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
+       if (ret == 0) {
+               while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) {
+                       WATCHDOG_RESET();
                        if (addr == 0)
                                spl_parse_image_header((struct image_header *)buf);
                        store_addr = addr + spl_image.load_addr;
                        size += res;
                        addr += res;
-                       memcpy((char *)(store_addr), buf, res);
+                       memcpy((char *)store_addr, buf, res);
                }
        } else {
-               printf("spl: ymodem err - %s\n", xyzModem_error(err));
-               hang();
+               WATCHDOG_RESET();
+               printf("Retrying...\n");
+               goto loop;
        }
 
        xyzModem_stream_close(&err);
index 56f4bcaf99453d04bac277b39a63688ed6836263..8e35e99a0df76ded98f8537f3d62d497b0df4c4b 100644 (file)
@@ -37,7 +37,7 @@
 #define BSP 0x08
 #define NAK 0x15
 #define CAN 0x18
-#define EOF 0x1A               /* ^Z for DOS officionados */
+#define EOF 0x1A               /* ^Z for DOS aficionados */
 
 #define USE_YMODEM_LENGTH
 
@@ -203,7 +203,7 @@ parse_num (char *s, unsigned long *val, char **es, char *delim)
 static int
 zm_dprintf (char *fmt, ...)
 {
-  int cur_console;
+  int cur_console __attribute__((unused));
   va_list args;
 
   va_start (args, fmt);
@@ -217,9 +217,10 @@ zm_dprintf (char *fmt, ...)
 #ifdef REDBOOT
   CYGACC_CALL_IF_SET_CONSOLE_COMM (cur_console);
 #endif
+  return 0;
 }
 
-static void
+static inline void
 zm_flush (void)
 {
 }
@@ -250,7 +251,7 @@ zm_dprintf (char *fmt, ...)
   return len;
 }
 
-static void
+static inline void
 zm_flush (void)
 {
 #ifdef REDBOOT
@@ -275,19 +276,19 @@ zm_dump_buf (void *buf, int len)
 static unsigned char zm_buf[2048];
 static unsigned char *zm_bp;
 
-static void
+static inline void
 zm_new (void)
 {
   zm_bp = zm_buf;
 }
 
-static void
+static inline void
 zm_save (unsigned char c)
 {
   *zm_bp++ = c;
 }
 
-static void
+static inline void
 zm_dump (int line)
 {
   zm_dprintf ("Packet at line: %d\n", line);
diff --git a/configs/tx28-40x1_defconfig b/configs/tx28-40x1_defconfig
new file mode 100644 (file)
index 0000000..b6d39bf
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_128M
+CONFIG_ARM=y
+CONFIG_TARGET_TX28=y
diff --git a/configs/tx28-40x1_noenv_defconfig b/configs/tx28-40x1_noenv_defconfig
new file mode 100644 (file)
index 0000000..cf59170
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_128M,ENV_IS_NOWHERE
+CONFIG_ARM=y
+CONFIG_TARGET_TX28=y
diff --git a/configs/tx28-40x2_defconfig b/configs/tx28-40x2_defconfig
new file mode 100644 (file)
index 0000000..8a90e59
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_256M
+CONFIG_ARM=y
+CONFIG_TARGET_TX28=y
diff --git a/configs/tx28-40x2_noenv_defconfig b/configs/tx28-40x2_noenv_defconfig
new file mode 100644 (file)
index 0000000..58ef67f
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_256M,ENV_IS_NOWHERE
+CONFIG_ARM=y
+CONFIG_TARGET_TX28=y
diff --git a/configs/tx28-40x3_defconfig b/configs/tx28-40x3_defconfig
new file mode 100644 (file)
index 0000000..d2af8c6
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_128M,SYS_NAND_BLOCKS=2048
+CONFIG_ARM=y
+CONFIG_TARGET_TX28=y
diff --git a/configs/tx28-40x3_noenv_defconfig b/configs/tx28-40x3_noenv_defconfig
new file mode 100644 (file)
index 0000000..6c85a34
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX28,SDRAM_SIZE=SZ_128M,SYS_NAND_BLOCKS=2048,ENV_IS_NOWHERE
+CONFIG_ARM=y
+CONFIG_TARGET_TX28=y
diff --git a/configs/tx28-41x0_defconfig b/configs/tx28-41x0_defconfig
new file mode 100644 (file)
index 0000000..8379392
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX28_S,SDRAM_SIZE=SZ_64M
+CONFIG_ARM=y
+CONFIG_TARGET_TX28=y
diff --git a/configs/tx28-41x0_noenv_defconfig b/configs/tx28-41x0_noenv_defconfig
new file mode 100644 (file)
index 0000000..67430cd
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX28_S,SDRAM_SIZE=SZ_64M,ENV_IS_NOWHERE
+CONFIG_ARM=y
+CONFIG_TARGET_TX28=y
diff --git a/configs/tx48_defconfig b/configs/tx48_defconfig
new file mode 100644 (file)
index 0000000..07dd3a6
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_MPU_CLK=720,SYS_DDR_CLK=400
+CONFIG_ARM=y
+CONFIG_TARGET_TX48=y
diff --git a/configs/tx51-8xx0_defconfig b/configs/tx51-8xx0_defconfig
new file mode 100644 (file)
index 0000000..4e6ddb0
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_CPU_CLK=800,NR_DRAM_BANKS=1
+CONFIG_ARM=y
+CONFIG_TARGET_TX51=y
diff --git a/configs/tx51-8xx1_2_defconfig b/configs/tx51-8xx1_2_defconfig
new file mode 100644 (file)
index 0000000..3dd883d
--- /dev/null
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_CPU_CLK=800,NR_DRAM_BANKS=2
+CONFIG_ARM=y
+CONFIG_TARGET_TX51=y
diff --git a/configs/tx53-1232_defconfig b/configs/tx53-1232_defconfig
new file mode 100644 (file)
index 0000000..4cf3dd8
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_SYS_EXTRA_OPTIONS=NR_DRAM_BANKS=2,SYS_SDRAM_SIZE=SZ_2G
+CONFIG_ARM=y
+CONFIG_TARGET_TX53=y
+CONFIG_TARGET_TX53_1232=y
+CONFIG_TX53_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FEC_MXC_PHYADDR=0
diff --git a/configs/tx53-x030_defconfig b/configs/tx53-x030_defconfig
new file mode 100644 (file)
index 0000000..c7e1486
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=NR_DRAM_BANKS=1
+CONFIG_ARM=y
+CONFIG_TARGET_TX53=y
+CONFIG_TARGET_TX53_X030=y
+CONFIG_TX53_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_CMD_I2C=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FEC_MXC_PHYADDR=0
diff --git a/configs/tx53-x130_defconfig b/configs/tx53-x130_defconfig
new file mode 100644 (file)
index 0000000..e4b7776
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_SYS_EXTRA_OPTIONS=NR_DRAM_BANKS=1,SYS_LVDS_IF
+CONFIG_ARM=y
+CONFIG_TARGET_TX53=y
+CONFIG_TARGET_TX53_X130=y
+CONFIG_TX53_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FEC_MXC_PHYADDR=0
diff --git a/configs/tx53-x131_defconfig b/configs/tx53-x131_defconfig
new file mode 100644 (file)
index 0000000..8fd9ada
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_SYS_EXTRA_OPTIONS=NR_DRAM_BANKS=2,SYS_LVDS_IF
+CONFIG_ARM=y
+CONFIG_TARGET_TX53=y
+CONFIG_TARGET_TX53_X131=y
+CONFIG_TX53_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_ENV_IS_IN_NAND=y
+CONFIG_FEC_MXC_PHYADDR=0
diff --git a/configs/tx6q-1020_defconfig b/configs/tx6q-1020_defconfig
new file mode 100644 (file)
index 0000000..3b441cf
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX6_REV=0x2
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_1020=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6q-1020_mfg_defconfig b/configs/tx6q-1020_mfg_defconfig
new file mode 100644 (file)
index 0000000..228be88
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX6_REV=0x2
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_1020=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6q-1020_noenv_defconfig b/configs/tx6q-1020_noenv_defconfig
new file mode 100644 (file)
index 0000000..524cb99
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=TX6_REV=0x2
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_1020=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6q-10x0_defconfig b/configs/tx6q-10x0_defconfig
new file mode 100644 (file)
index 0000000..f5c3bf5
--- /dev/null
@@ -0,0 +1,20 @@
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_10X0=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6q-10x0_mfg_defconfig b/configs/tx6q-10x0_mfg_defconfig
new file mode 100644 (file)
index 0000000..9b07e49
--- /dev/null
@@ -0,0 +1,20 @@
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_10X0=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6q-10x0_noenv_defconfig b/configs/tx6q-10x0_noenv_defconfig
new file mode 100644 (file)
index 0000000..c053376
--- /dev/null
@@ -0,0 +1,20 @@
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_10X0=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6q-11x0_defconfig b/configs/tx6q-11x0_defconfig
new file mode 100644 (file)
index 0000000..975bdf6
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_LVDS_IF
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_11X0=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6q-11x0_mfg_defconfig b/configs/tx6q-11x0_mfg_defconfig
new file mode 100644 (file)
index 0000000..e3a2132
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_LVDS_IF
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_11X0=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6q-11x0_noenv_defconfig b/configs/tx6q-11x0_noenv_defconfig
new file mode 100644 (file)
index 0000000..4362900
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_LVDS_IF
+CONFIG_ARM=y
+CONFIG_MX6Q=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6Q_11X0=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6s-8034_defconfig b/configs/tx6s-8034_defconfig
new file mode 100644 (file)
index 0000000..b59b96b
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=16
+CONFIG_ARM=y
+CONFIG_MX6S=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6S_8034=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6s-8034_mfg_defconfig b/configs/tx6s-8034_mfg_defconfig
new file mode 100644 (file)
index 0000000..74e3feb
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=16
+CONFIG_ARM=y
+CONFIG_MX6S=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6S_8034=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6s-8034_noenv_defconfig b/configs/tx6s-8034_noenv_defconfig
new file mode 100644 (file)
index 0000000..d3cdd4d
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=16
+CONFIG_ARM=y
+CONFIG_MX6S=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6S_8034=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6s-8035_defconfig b/configs/tx6s-8035_defconfig
new file mode 100644 (file)
index 0000000..6a06f03
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024,SYS_SDRAM_BUS_WIDTH=32
+CONFIG_ARM=y
+CONFIG_MX6S=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6S_8035=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6s-8035_mfg_defconfig b/configs/tx6s-8035_mfg_defconfig
new file mode 100644 (file)
index 0000000..5706c99
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024,SYS_SDRAM_BUS_WIDTH=32
+CONFIG_ARM=y
+CONFIG_MX6S=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6S_8035=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6s-8035_noenv_defconfig b/configs/tx6s-8035_noenv_defconfig
new file mode 100644 (file)
index 0000000..a00b5dd
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024,SYS_SDRAM_BUS_WIDTH=32
+CONFIG_ARM=y
+CONFIG_MX6S=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6S_8035=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-8011_defconfig b/configs/tx6u-8011_defconfig
new file mode 100644 (file)
index 0000000..eab8f56
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8011=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-8011_mfg_defconfig b/configs/tx6u-8011_mfg_defconfig
new file mode 100644 (file)
index 0000000..d72a09b
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8011=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-8011_noenv_defconfig b/configs/tx6u-8011_noenv_defconfig
new file mode 100644 (file)
index 0000000..677ad99
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8011=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-8012_defconfig b/configs/tx6u-8012_defconfig
new file mode 100644 (file)
index 0000000..ae834e6
--- /dev/null
@@ -0,0 +1,23 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_NAND_BLOCKS=2048
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8012=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
diff --git a/configs/tx6u-8012_mfg_defconfig b/configs/tx6u-8012_mfg_defconfig
new file mode 100644 (file)
index 0000000..ec5692b
--- /dev/null
@@ -0,0 +1,23 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_NAND_BLOCKS=2048
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8012=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
diff --git a/configs/tx6u-8012_noenv_defconfig b/configs/tx6u-8012_noenv_defconfig
new file mode 100644 (file)
index 0000000..a5753b1
--- /dev/null
@@ -0,0 +1,23 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_NAND_BLOCKS=2048
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8012=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
diff --git a/configs/tx6u-8033_defconfig b/configs/tx6u-8033_defconfig
new file mode 100644 (file)
index 0000000..9a11a46
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8033=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-8033_mfg_defconfig b/configs/tx6u-8033_mfg_defconfig
new file mode 100644 (file)
index 0000000..3f0f977
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8033=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-8033_noenv_defconfig b/configs/tx6u-8033_noenv_defconfig
new file mode 100644 (file)
index 0000000..dfb49be
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=MMC_BOOT_SIZE=1024
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_8033=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-80x0_defconfig b/configs/tx6u-80x0_defconfig
new file mode 100644 (file)
index 0000000..fb33c2a
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_80X0=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
diff --git a/configs/tx6u-80x0_mfg_defconfig b/configs/tx6u-80x0_mfg_defconfig
new file mode 100644 (file)
index 0000000..e72b3fb
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_80X0=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
diff --git a/configs/tx6u-80x0_noenv_defconfig b/configs/tx6u-80x0_noenv_defconfig
new file mode 100644 (file)
index 0000000..2cc8c6b
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_80X0=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
diff --git a/configs/tx6u-8111_defconfig b/configs/tx6u-8111_defconfig
new file mode 100644 (file)
index 0000000..cbe9d89
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32,SYS_LVDS_IF
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_81X0=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-8111_mfg_defconfig b/configs/tx6u-8111_mfg_defconfig
new file mode 100644 (file)
index 0000000..f956d1f
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32,SYS_LVDS_IF
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_81X0=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-8111_noenv_defconfig b/configs/tx6u-8111_noenv_defconfig
new file mode 100644 (file)
index 0000000..29c5674
--- /dev/null
@@ -0,0 +1,21 @@
+CONFIG_SYS_EXTRA_OPTIONS=SYS_SDRAM_BUS_WIDTH=32,SYS_LVDS_IF
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_81X0=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
diff --git a/configs/tx6u-81x0_defconfig b/configs/tx6u-81x0_defconfig
new file mode 100644 (file)
index 0000000..f303f4a
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_81X0=y
+CONFIG_TX6_UBOOT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
diff --git a/configs/tx6u-81x0_mfg_defconfig b/configs/tx6u-81x0_mfg_defconfig
new file mode 100644 (file)
index 0000000..1bc01d5
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_81X0=y
+CONFIG_TX6_UBOOT_MFG=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
diff --git a/configs/tx6u-81x0_noenv_defconfig b/configs/tx6u-81x0_noenv_defconfig
new file mode 100644 (file)
index 0000000..4a457e1
--- /dev/null
@@ -0,0 +1,22 @@
+CONFIG_ARM=y
+CONFIG_MX6DL=y
+CONFIG_TARGET_TX6=y
+CONFIG_TARGET_TX6U_81X0=y
+CONFIG_TX6_UBOOT_NOENV=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_PING=y
+CONFIG_BOOTP_SUBNETMASK=y
+CONFIG_BOOTP_GATEWAY=y
+CONFIG_BOOTP_DNS=y
+CONFIG_MMC=y
+CONFIG_FSL_ESDHC=y
+CONFIG_FSL_USDHC=y
+CONFIG_LCD=y
+CONFIG_NET=y
+CONFIG_NETDEVICES=y
+CONFIG_FEC_MXC=y
+CONFIG_IMX_WATCHDOG=y
+CONFIG_CMD_I2C=y
+CONFIG_NAND=y
+CONFIG_NAND_MXS=y
index 43485c9148b0f404e91cb0f45f9a3c76b2267578..18fcc7b15633fdb3813152875e6f1b3ba4eb602c 100644 (file)
@@ -29,6 +29,9 @@ static const struct block_drvr block_drvr[] = {
 #if defined(CONFIG_CMD_IDE)
        { .name = "ide", .get_dev = ide_get_dev, },
 #endif
+#if defined(CONFIG_CMD_PATA)
+       { .name = "pata", .get_dev = pata_get_dev, },
+#endif
 #if defined(CONFIG_CMD_SATA)
        {.name = "sata", .get_dev = sata_get_dev, },
 #endif
diff --git a/doc/README.KARO b/doc/README.KARO
new file mode 100755 (executable)
index 0000000..9fc611e
--- /dev/null
@@ -0,0 +1,39 @@
+                             Building & Flashing U-Boot for TX28
+                             ===================================
+
+Building U-Boot
+---------------
+
+Unpacking the source
+--------------------
+mkdir u-boot
+cd u-boot
+tar -xjf /cdrom/U-Boot/u-boot-src.tar.bz2
+
+Compiling U-Boot
+----------------
+export ARCH=arm
+export CROSS_COMPILE=arm-926ejs-linux-gnueabi-
+make tx28_config
+make
+
+
+Flashing U-Boot Image
+---------------------
+Load the U-Boot image with sbloader (either the Windows version or the
+Linux version) and use the builtin 'romupdate' command to program the
+image into the flash.
+
+Put the u-boot.sb file in the TFTP server data directory (usually
+/tftpboot).
+
+Load the U-Boot image:
+Enter the following commands at the U-Boot prompt
+set autostart no
+set autoload yes
+set bootfile u-boot.sb
+bootp
+romupdate
+
+Power down the module, make sure the BOOT_MODE jumper (ST3) is removed
+and re-apply power to start from flash.
diff --git a/doc/README.KARO-FDT b/doc/README.KARO-FDT
new file mode 100644 (file)
index 0000000..092276f
--- /dev/null
@@ -0,0 +1,52 @@
+                                 Managing the device tree data in U-Boot
+                                =======================================
+
+The 'fdt' command can be used to manipulate the device tree (DT) data
+that is passed from U-Boot to Linux.
+
+- 'fdt boardsetup' (which is automatically being run by the 'bootm'
+  command) will disable some device nodes according to environment
+  settings:
+
+Environment setting            disabled nodes
+---------------------------------------------
+otg_mode=host                  usbh1
+otg_mode=device                        usbotg
+otg_mode=<UNSET>               <both of the above> + usbphy
+
+touchpanel=edt-ft5x06          ti,tsc2007
+touchpanel=tsc2007             edt,edt-ft5x06
+touchpanel=<UNSET>             <both of the above>
+
+Note: This command is automatically executed when booting Linux via
+      'run bootm_cmd'.
+
+- 'fdt rm' and 'fdt mknode' can be used to remove/create additional nodes.
+
+- 'fdt set' can be used to change properties or add new properties to
+  existing nodes.
+
+The whole DT data can be saved to and reloaded from the flash partition
+'dtb' (or any other partition):
+  nand erase.part dtb
+  nand write.jffs2 ${fdtaddr} dtb ${fdtsize}
+The predefined variable 'fdtsave' contains these commands as a macro
+to facilitate the update of the 'dtb' partition with the currently
+active FDT. Thus:
+  'run fdtsave' will achive the same as above commands.
+
+(Re)Loading the DT data from flash:
+  nand read ${fdtaddr} dtb
+
+Enabling/Disabling individual nodes in FDT:
+Most device nodes in FDT use a property named 'status' that can be set
+to either 'disabled' or 'okay' to disable or enable the device.
+This property can be manipulated
+  fdt set /<path> status disabled
+  fdt set /<path> status okay
+
+e.g.: fdt set /soc/aips-bus@02100000/ethernet@02188000 status disabled
+      will disable the ethernet interface on a TX6.
+
+Refer to Linux/TX*-driver.pdf for a complete list of the device paths
+for the individual TX modules.
diff --git a/doc/README.KARO-TX28 b/doc/README.KARO-TX28
new file mode 100644 (file)
index 0000000..c5a1fe1
--- /dev/null
@@ -0,0 +1,111 @@
+                                        U-Boot for TX28
+                                        ===============
+
+Building U-Boot
+---------------
+
+Note: There are currently two variants of the TX28 module, that
+      require slightly different U-Boot configurations. They are
+      distinguished through the last digit of the module name. Replace
+      the '?' in the following description with the corresponding
+      number from your TX28 module.
+      E.g. TX28-4031 => 'make tx28-40x1_config'
+
+Unpacking the source
+--------------------
+mkdir u-boot
+cd u-boot
+tar -xjf /cdrom/U-Boot/u-boot-src.tar.bz2
+
+Alternatively you can access the current source via the git repository:
+git://git.karo-electronics.de/karo-tx-uboot.git master
+
+
+Compiling U-Boot
+----------------
+export ARCH=arm
+export CROSS_COMPILE=arm-926ejs-linux-gnueabi-
+make tx28-4?x?_config            (see above Note!)
+make
+
+
+Flashing U-Boot Image
+---------------------
+If you want to replace a working U-Boot with a new version, you can
+load the new U-Boot image via TFTP or SD-Card and write it to flash
+with the 'romupdate' command.
+
+If you want to revive a bricked module, U-Boot can be downloaded via
+USB with the 'sbloader' tool in recovery boot mode (Bootmode jumper ST3
+on Starterkit-5 baseboard closed). See TX28_U-Boot.pdf for details.
+
+e.g.: /cdrom/Flashtools/Linux/sbloader/sbloader-x86_32 -s /cdrom/U-Boot/u-boot-tx28-4031.bin
+(This command can be used from within the ARMSK-VM)
+
+
+U-Boot Features
+---------------
+
+Environment variables:
+boot_mode     selects which boot script will be used by 'bootcmd' to
+             boot the application (Linux)
+             supported values:
+             nand: (default) load kernel from NAND partition 'linux'
+                             and mount rootfs (fstype UBIFS)
+                             from partition 'rootfs'. 
+             mmc:            load kernel from file 'uImage' on first
+                             partition (FAT) on (first) SD/MMC card
+                             and mount rootfs (fstype autodetected)
+                             from second partition.
+             net:            load kernel image via tftp (file uImage)
+                             and mount rootfs via NFS. This requires
+                             the additional variables 'nfsroot'
+                             (path to rootfs on NFS server) and
+                             'nfs_server' (hostname or IP address of
+                             NFS server) to be set.
+             jffs2: (legacy) load kernel from NAND partition 'linux'
+                             and mount rootfs (fstype JFFS2)
+                             from partition 'rootfs'.
+
+cpu_clk       <CPU freq [MHz]> CPU clock frequency set after boot.
+
+touchpanel    {tsc2007|edt-ft5x06|imx28-lradc} type of touchpanel.
+             No touchpanel will be enabled when unset.
+
+otg_mode      [host|device|none] operation mode of the USBOTG port
+
+video_mode    <one of the display names from the Glyn Family Concept or
+             a video mode as understood by Linux fb_find_mode() function
+              (e.g.: 640x480MR-24@60)>
+             LCD interface will be disabled when unset.
+
+baseboard     {stk5-v3|stk5-v5} selects type of baseboard
+             'stk5-v5' setting disables USB Host mode on USBOTG port
+             and redefines the LCD0 pin as CAN transceiver control pin.
+             Strings not starting in 'stk5' prevent the STK5 specific
+             pad initialization to be done.
+
+splashimage   either: memory address (e.g. ${loadaddr}) of a BMP file
+             to be displayed instead of the built-in logo. Since NAND
+             flash is not accessible in a memory mapped fashion,
+             U-Boot will try to load the contents of the flash
+             partition 'logo.bmp' to the address given with
+             'splashimage'.
+
+             or: the name of an MTD partition, that contains a raw
+             dump of the frame buffer contents which will be loaded
+             to the framebuffer.
+
+splashpos     (when 'splashimage' contains a memory address) the
+             position ('x,y') on the screen at which the BMP image
+             will be displayed.
+             Setting splashpos to 'm,m' will center the image on the
+             screen.
+
+Note: Some variables (like 'cpu_clk' or 'splashimage') may render the
+      board unbootable if incorrectly set. Therefore these variables
+      will not be evaluated in case the board has been reset through a
+      watchdog reset or <CTRL-C> is detected on the serial console
+      during startup to give the user a chance to recover from this
+      situation. You should press and hold <CTRL-C> before applying
+      power to the module, for this to work.
diff --git a/doc/README.KARO-TX48 b/doc/README.KARO-TX48
new file mode 100644 (file)
index 0000000..ed50e81
--- /dev/null
@@ -0,0 +1,83 @@
+                                        U-Boot for TX48
+                                        ===============
+
+Building U-Boot
+---------------
+
+Unpacking the source
+--------------------
+mkdir u-boot
+cd u-boot
+tar -xjf /cdrom/U-Boot/u-boot-src.tar.bz2
+
+Alternatively you can access the current source via the git repository:
+git://git.karo-electronics.de/karo-tx-uboot.git master
+
+
+Compiling U-Boot
+----------------
+export ARCH=arm
+export CROSS_COMPILE=arm-cortexa8-linux-gnueabi-
+make tx48_config
+make
+
+
+Flashing U-Boot Image
+---------------------
+If you want to replace a working U-Boot with a new version, you can
+load the new U-Boot image via TFTP and program it like any other flash
+partition with:
+nand erase.part u-boot;nand write.trimffs ${fileaddr} u-boot ${filesize}
+
+If you want to revive a bricked module, U-Boot can be downloaded via
+xmodem protocol over the serial port in recovery boot mode (Jumper ST3
+on Starterkit-5 baseboard closed). See TX48-U-Boot.pdf for details.
+
+
+U-Boot Features
+---------------
+
+Environment variables:
+
+cpu_clk       <CPU freq [MHz]> CPU clock frequency set after boot.
+
+touchpanel    {tsc2007|edt-ft5x06|am3359-tscadc} type of touchpanel.
+             No touchpanel will be enabled when unset.
+
+otg_mode      [host|device|none] operation mode of the USBOTG port
+
+video_mode    <one of the display names from the Glyn Family Concept or
+             a video mode as understood by Linux fb_find_mode() function
+              (e.g.: 640x480MR-24@60)>
+             LCD interface will be disabled when unset.
+
+baseboard     {stk5-v3|stk5-v5} selects type of baseboard
+             'stk5-v5' setting disables USB Host mode on USBOTG port
+             and redefines the LCD0 pin as CAN transceiver control pin.
+             Strings not starting in 'stk5' prevent the STK5 specific
+             pad initialization to be done.
+
+splashimage   either: memory address (e.g. ${loadaddr}) of a BMP file
+             to be displayed instead of the built-in logo. Since NAND
+             flash is not accessible in a memory mapped fashion,
+             U-Boot will try to load the contents of the flash
+             partition 'logo.bmp' to the address given with
+             'splashimage'.
+
+             or: the name of an MTD partition, that contains a raw
+             dump of the frame buffer contents which will be loaded
+             to the framebuffer.
+
+splashpos     (when 'splashimage' contains a memory address) the
+             position ('x,y') on the screen at which the BMP image
+             will be displayed.
+             Setting splashpos to 'm,m' will center the image on the
+             screen.
+
+Note: Some variables (like 'cpu_clk' or 'splashimage') may render the
+      board unbootable if incorrectly set. Therefore these variables
+      will not be evaluated in case the board has been reset through a
+      watchdog reset or <CTRL-C> is detected on the serial console
+      during startup to give the user a chance to recover from this
+      situation. You should press and hold <CTRL-C> before applying
+      power to the module, for this to work.
diff --git a/doc/README.KARO-TX51 b/doc/README.KARO-TX51
new file mode 100644 (file)
index 0000000..30c9f1e
--- /dev/null
@@ -0,0 +1,111 @@
+                                        U-Boot for TX51
+                                        ===============
+
+Building U-Boot
+---------------
+
+Note: There are currently three variants of the TX51 module, that
+      require slightly different U-Boot configurations. They are
+      distinguished through the last digit of the module name
+      suffix. The configuration names depending on the last digit of
+      the module name are:
+      TX51-8??0                 tx51-8xx0_config
+      TX51-8??1                 tx51-8xx1_2_config
+      TX51-8??2                 tx51-8xx1_2_config
+
+
+Unpacking the source
+--------------------
+mkdir u-boot
+cd u-boot
+tar -xjf /cdrom/U-Boot/u-boot-src.tar.bz2
+
+Alternatively you can access the current source via the git repository:
+git://git.karo-electronics.de/karo-tx-uboot.git master
+
+
+Compiling U-Boot
+----------------
+export ARCH=arm
+export CROSS_COMPILE=arm-cortexa8-linux-gnueabi-
+make tx51-8xx?_config            (see above Note!)
+make
+
+
+Flashing U-Boot Image
+---------------------
+If you want to replace a working U-Boot with a new version, you can
+load the new U-Boot image via TFTP and program it like any other flash
+partition with:
+nand erase.part u-boot;nand write ${fileaddr} u-boot ${filesize}
+
+If you want to revive a bricked module, you can use one of the
+flashtools provided with the BSP to reprogram the flash.
+
+
+U-Boot Features
+---------------
+
+Environment variables:
+boot_mode     selects which boot script will be used by 'bootcmd' to
+             boot the application (Linux)
+             supported values:
+             nand: (default) load kernel from NAND partition 'linux'
+                             and mount rootfs (fstype UBIFS)
+                             from partition 'rootfs'. 
+             mmc:            load kernel from file 'uImage' on first
+                             partition (FAT) on (first) SD/MMC card
+                             and mount rootfs (fstype autodetected)
+                             from second partition.
+             net:            load kernel image via tftp (file uImage)
+                             and mount rootfs via NFS. This requires
+                             the additional variables 'nfsroot'
+                             (path to rootfs on NFS server) and
+                             'nfs_server' (hostname or IP address of
+                             NFS server) to be set.
+             jffs2: (legacy) load kernel from NAND partition 'linux'
+                             and mount rootfs (fstype JFFS2)
+                             from partition 'rootfs'.
+
+cpu_clk       <CPU freq [MHz]> CPU clock frequency set after boot.
+
+touchpanel    {tsc2007|edt-ft5x06} type of touchpanel.
+             No touchpanel will be enabled when unset.
+
+otg_mode      [host|device|none] operation mode of the USBOTG port
+
+video_mode    <one of the display names from the Glyn Family Concept or
+             a video mode as understood by Linux fb_find_mode() function
+              (e.g.: 640x480MR-24@60)>
+             LCD interface will be disabled when unset.
+
+baseboard     {stk5-v3|stk5-v5} selects type of baseboard
+             'stk5-v5' setting disables USB Host mode on USBOTG port
+             and redefines the LCD0 pin as CAN transceiver control pin.
+             Strings not starting in 'stk5' prevent the STK5 specific
+             pad initialization to be done.
+
+splashimage   either: memory address (e.g. ${loadaddr}) of a BMP file
+             to be displayed instead of the built-in logo. Since NAND
+             flash is not accessible in a memory mapped fashion,
+             U-Boot will try to load the contents of the flash
+             partition 'logo.bmp' to the address given with
+             'splashimage'.
+
+             or: the name of an MTD partition, that contains a raw
+             dump of the frame buffer contents which will be loaded
+             to the framebuffer.
+
+splashpos     (when 'splashimage' contains a memory address) the
+             position ('x,y') on the screen at which the BMP image
+             will be displayed.
+             Setting splashpos to 'm,m' will center the image on the
+             screen.
+
+Note: Some variables (like 'cpu_clk' or 'splashimage') may render the
+      board unbootable if incorrectly set. Therefore these variables
+      will not be evaluated in case the board has been reset through a
+      watchdog reset or <CTRL-C> is detected on the serial console
+      during startup to give the user a chance to recover from this
+      situation. You should press and hold <CTRL-C> before applying
+      power to the module, for this to work.
diff --git a/doc/README.KARO-TX53 b/doc/README.KARO-TX53
new file mode 100644 (file)
index 0000000..b20a759
--- /dev/null
@@ -0,0 +1,113 @@
+                                        U-Boot for TX53
+                                        ===============
+
+Building U-Boot
+---------------
+
+Note: There are currently two variants of the TX53 module, that
+      require slightly different U-Boot configurations. The mapping
+      between module names and U-Boot config make targets is as
+      following:
+
+      Module Name       U-Boot config target
+      =====================================
+      TX53-8030                tx53-x030_config'
+      TX53-8130                tx53-x130_config'
+      TX53-1030                tx53-x030_config'
+      TX53-1331                tx53-x131_config'
+
+Unpacking the source
+--------------------
+mkdir u-boot
+cd u-boot
+tar -xjf /cdrom/U-Boot/u-boot-src.tar.bz2
+
+Alternatively you can access the current source via the git repository:
+git://git.karo-electronics.de/karo-tx-uboot.git master
+
+
+Compiling U-Boot
+----------------
+export ARCH=arm
+export CROSS_COMPILE=arm-cortexa8-linux-gnueabi-
+make tx53-x?3?_config            (see above Note!)
+make
+
+
+Flashing U-Boot Image
+---------------------
+If you want to replace a working U-Boot with a new version, you can
+load the new U-Boot image via TFTP and program it like any other flash
+partition with:
+nand erase.part u-boot;nand write ${fileaddr} u-boot ${filesize}
+
+If you want to revive a bricked module, you can use one of the
+flashtools provided with the BSP to reprogram the flash.
+
+
+U-Boot Features
+---------------
+
+Environment variables:
+boot_mode     selects which boot script will be used by 'bootcmd' to
+             boot the application (Linux)
+             supported values:
+             nand: (default) load kernel from NAND partition 'linux'
+                             and mount rootfs (fstype UBIFS)
+                             from partition 'rootfs'. 
+             mmc:            load kernel from file 'uImage' on first
+                             partition (FAT) on (first) SD/MMC card
+                             and mount rootfs (fstype autodetected)
+                             from second partition.
+             net:            load kernel image via tftp (file uImage)
+                             and mount rootfs via NFS. This requires
+                             the additional variables 'nfsroot'
+                             (path to rootfs on NFS server) and
+                             'nfs_server' (hostname or IP address of
+                             NFS server) to be set.
+             jffs2: (legacy) load kernel from NAND partition 'linux'
+                             and mount rootfs (fstype JFFS2)
+                             from partition 'rootfs'.
+
+cpu_clk       <CPU freq [MHz]> CPU clock frequency set after boot.
+
+touchpanel    {tsc2007|edt-ft5x06|egalax_ts} type of touchpanel.
+             No touchpanel will be enabled when unset.
+
+otg_mode      [host|device|none] operation mode of the USBOTG port
+
+video_mode    <one of the display names from the Glyn Family Concept or
+             a video mode as understood by Linux fb_find_mode() function
+              (e.g.: 640x480MR-24@60)>
+             LCD interface will be disabled when unset.
+
+baseboard     {stk5-v3|stk5-v5} selects type of baseboard
+             'stk5-v5' setting disables USB Host mode on USBOTG port
+             and redefines the LCD0 pin as CAN transceiver control pin.
+             Strings not starting in 'stk5' prevent the STK5 specific
+             pad initialization to be done.
+
+splashimage   either: memory address (e.g. ${loadaddr}) of a BMP file
+             to be displayed instead of the built-in logo. Since NAND
+             flash is not accessible in a memory mapped fashion,
+             U-Boot will try to load the contents of the flash
+             partition 'logo.bmp' to the address given with
+             'splashimage'.
+
+             or: the name of an MTD partition, that contains a raw
+             dump of the frame buffer contents which will be loaded
+             to the framebuffer.
+
+splashpos     (when 'splashimage' contains a memory address) the
+             position ('x,y') on the screen at which the BMP image
+             will be displayed.
+             Setting splashpos to 'm,m' will center the image on the
+             screen.
+
+Note: Some variables (like 'cpu_clk' or 'splashimage') may render the
+      board unbootable if incorrectly set. Therefore these variables
+      will not be evaluated in case the board has been reset through a
+      watchdog reset or <CTRL-C> is detected on the serial console
+      during startup to give the user a chance to recover from this
+      situation. You should press and hold <CTRL-C> before applying
+      power to the module, for this to work.
diff --git a/doc/README.KARO-TX6 b/doc/README.KARO-TX6
new file mode 100644 (file)
index 0000000..334b58c
--- /dev/null
@@ -0,0 +1,135 @@
+                                        U-Boot for TX6
+                                        ==============
+
+Building U-Boot
+---------------
+
+Note: There are currently seven variants of the TX6 module, that
+      require slightly different U-Boot configurations. They are
+      distinguished through the 'TX6' suffix 'Q' or 'U' and the
+      numerical suffix of the module name. Replace the '?' in the
+      following description with the corresponding digits from your
+      TX6 module.
+      E.g. TX6Q-1010 => 'make tx6q-1010_config'
+
+Unpacking the source
+--------------------
+mkdir u-boot
+cd u-boot
+tar -xjf /cdrom/U-Boot/u-boot-src.tar.bz2
+
+Alternatively you can access the current source via the git repository:
+git://git.karo-electronics.de/karo-tx-uboot.git master
+
+
+Compiling U-Boot
+----------------
+export ARCH=arm
+export CROSS_COMPILE=arm-cortexa9-linux-gnueabi-
+make tx6?-????_config            (see above Note!)
+make
+
+
+Flashing U-Boot Image
+---------------------
+For all TX6 modules except TX6Q-1020:
+-------------------------------------
+If you want to replace a working U-Boot with a new version, you can
+load the new U-Boot image via TFTP or SD-Card and write it to flash
+with the 'romupdate' command.
+
+If you want to revive a bricked module, U-Boot can be downloaded via
+USB with the 'sbloader' tool in recovery boot mode (Bootmode jumper ST3
+on Starterkit-5 baseboard closed). See TX6_U-Boot.pdf for details.
+
+e.g.: /cdrom/Flashtools/Linux/sbloader/sbloader-x86_32 -m -s /cdrom/U-Boot/target/u-boot-tx6q-1010.bin
+(This command can be used from within the ARMSK-VM)
+
+For TX6Q-1020:
+--------------
+The TX6Q-1020 is equipped with eMMC instead of NAND flash.
+The bootloader, U-Boot environment and DTB is stored in the first boot
+partition of the eMMC device. The command to update the bootloader
+TX6Q U-Boot > set autostart n
+TX6Q U-Boot > tftp u-boot-tx6q-1020.bin
+TX6Q U-Boot > mmc open 0 1
+TX6Q U-Boot > mmc write ${fileaddr} 0 400
+TX6Q U-Boot > mmc close 0 1
+
+
+MfgTool
+-------
+For Windows users the application MfgTool allows the (re-)flashing of
+U-Boot. For more information either see:
+
+\U-Boot\TX6Q_U-Boot.pdf
+\STK5_TX6Q_Quickstart_Guide.pdf
+\Flashtools\Windows\Mfgtools-TX6...
+
+
+U-Boot Features
+---------------
+
+Environment variables:
+boot_mode     selects which boot script will be used by 'bootcmd' to
+             boot the application (Linux)
+             supported values:
+             nand: (default) load kernel from NAND partition 'linux'
+                             and mount rootfs (fstype UBIFS)
+                             from partition 'rootfs'. 
+             mmc:            load kernel from file 'uImage' on first
+                             partition (FAT) on (first) SD/MMC card
+                             and mount rootfs (fstype autodetected)
+                             from second partition.
+             net:            load kernel image via tftp (file uImage)
+                             and mount rootfs via NFS. This requires
+                             the additional variables 'nfsroot'
+                             (path to rootfs on NFS server) and
+                             'nfs_server' (hostname or IP address of
+                             NFS server) to be set.
+             jffs2: (legacy) load kernel from NAND partition 'linux'
+                             and mount rootfs (fstype JFFS2)
+                             from partition 'rootfs'.
+
+cpu_clk       <CPU freq [MHz]> CPU clock frequency set after boot.
+
+touchpanel    {tsc2007|edt-ft5x06|egalax_ts} type of touchpanel.
+             No touchpanel will be enabled when unset.
+
+otg_mode      [host|device|none] operation mode of the USBOTG port
+
+video_mode    <one of the display names from the Glyn Family Concept or
+             a video mode as understood by Linux fb_find_mode() function
+              (e.g.: 640x480MR-24@60)>
+             LCD interface will be disabled when unset.
+
+baseboard     {stk5-v3|stk5-v5} selects type of baseboard
+             'stk5-v5' setting disables USB Host mode on USBOTG port
+             and redefines the LCD0 pin as CAN transceiver control pin.
+             Strings not starting in 'stk5' prevent the STK5 specific
+             pad initialization to be done.
+
+splashimage   either: memory address (e.g. ${loadaddr}) of a BMP file
+             to be displayed instead of the built-in logo. Since NAND
+             flash is not accessible in a memory mapped fashion,
+             U-Boot will try to load the contents of the flash
+             partition 'logo.bmp' to the address given with
+             'splashimage'.
+
+             or: the name of an MTD partition, that contains a raw
+             dump of the frame buffer contents which will be loaded
+             to the framebuffer.
+
+splashpos     (when 'splashimage' contains a memory address) the
+             position ('x,y') on the screen at which the BMP image
+             will be displayed.
+             Setting splashpos to 'm,m' will center the image on the
+             screen.
+
+Note: Some variables (like 'cpu_clk' or 'splashimage') may render the
+      board unbootable if incorrectly set. Therefore these variables
+      will not be evaluated in case the board has been reset through a
+      watchdog reset or <CTRL-C> is detected on the serial console
+      during startup to give the user a chance to recover from this
+      situation. You should press and hold <CTRL-C> before applying
+      power to the module, for this to work.
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..25cc5f80c8723a42be1480a6bdaf39ddfc2711d6 100644 (file)
@@ -0,0 +1,14 @@
+config APBH_DMA
+       bool "Freescale MXS and i.MX6 APBH DMA support"
+       default y
+       depends on MX28 || MX6
+
+config APBH_DMA_BURST
+       bool "Enable DMA burst mode"
+       default y
+       depends on APBH_DMA
+
+config APBH_DMA_BURST8
+       bool "Use 8-beat DMA bursts"
+       default y
+       depends on APBH_DMA_BURST
index 22defcd7d9223be898b18cdc8ae1236a38272671..983111ad29e8a18b360322ba09b908cc4785eb8a 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/imx-common/regs-apbh.h>
 
 static struct mxs_dma_chan mxs_dma_channels[MXS_MAX_DMA_CHANNELS];
+static struct mxs_apbh_regs *apbh_regs = (struct mxs_apbh_regs *)MXS_APBH_BASE;
 
 /*
  * Test is the DMA channel is valid channel
@@ -31,12 +32,16 @@ int mxs_dma_validate_chan(int channel)
 {
        struct mxs_dma_chan *pchan;
 
-       if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS))
+       if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS)) {
+               printf("Invalid DMA channel %d\n", channel);
                return -EINVAL;
+       }
 
        pchan = mxs_dma_channels + channel;
-       if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED))
+       if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED)) {
+               printf("DMA channel %d not allocated\n", channel);
                return -EINVAL;
+       }
 
        return 0;
 }
@@ -65,8 +70,6 @@ static unsigned int mxs_dma_cmd_address(struct mxs_dma_desc *desc)
  */
 static int mxs_dma_read_semaphore(int channel)
 {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        uint32_t tmp;
        int ret;
 
@@ -83,7 +86,7 @@ static int mxs_dma_read_semaphore(int channel)
 }
 
 #ifndef        CONFIG_SYS_DCACHE_OFF
-void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
+static void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
 {
        uint32_t addr;
        uint32_t size;
@@ -94,7 +97,9 @@ void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
        flush_dcache_range(addr, addr + size);
 }
 #else
-inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc) {}
+static inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
+{
+}
 #endif
 
 /*
@@ -108,8 +113,6 @@ inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc) {}
  */
 static int mxs_dma_enable(int channel)
 {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        unsigned int sem;
        struct mxs_dma_chan *pchan;
        struct mxs_dma_desc *pdesc;
@@ -128,7 +131,7 @@ static int mxs_dma_enable(int channel)
 
        pdesc = list_first_entry(&pchan->active, struct mxs_dma_desc, node);
        if (pdesc == NULL)
-               return -EFAULT;
+               return -EINVAL;
 
        if (pchan->flags & MXS_DMA_FLAGS_BUSY) {
                if (!(pdesc->cmd.data & MXS_DMA_DESC_CHAIN))
@@ -151,12 +154,12 @@ static int mxs_dma_enable(int channel)
        } else {
                pchan->active_num += pchan->pending_num;
                pchan->pending_num = 0;
+               writel(1 << (channel + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET),
+                       &apbh_regs->hw_apbh_ctrl0_clr);
                writel(mxs_dma_cmd_address(pdesc),
                        &apbh_regs->ch[channel].hw_apbh_ch_nxtcmdar);
                writel(pchan->active_num,
                        &apbh_regs->ch[channel].hw_apbh_ch_sema);
-               writel(1 << (channel + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET),
-                       &apbh_regs->hw_apbh_ctrl0_clr);
        }
 
        pchan->flags |= MXS_DMA_FLAGS_BUSY;
@@ -180,8 +183,6 @@ static int mxs_dma_enable(int channel)
 static int mxs_dma_disable(int channel)
 {
        struct mxs_dma_chan *pchan;
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
 
        ret = mxs_dma_validate_chan(channel);
@@ -190,13 +191,12 @@ static int mxs_dma_disable(int channel)
 
        pchan = mxs_dma_channels + channel;
 
-       if (!(pchan->flags & MXS_DMA_FLAGS_BUSY))
+       if ((pchan->flags & MXS_DMA_FLAGS_BUSY)) {
+               printf("%s: DMA channel %d busy\n", __func__, channel);
                return -EINVAL;
-
+       }
        writel(1 << (channel + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET),
                &apbh_regs->hw_apbh_ctrl0_set);
-
-       pchan->flags &= ~MXS_DMA_FLAGS_BUSY;
        pchan->active_num = 0;
        pchan->pending_num = 0;
        list_splice_init(&pchan->active, &pchan->done);
@@ -209,14 +209,12 @@ static int mxs_dma_disable(int channel)
  */
 static int mxs_dma_reset(int channel)
 {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
 #if defined(CONFIG_MX23)
-       uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set);
+       uint32_t *setreg = &apbh_regs->hw_apbh_ctrl0_set;
        uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET;
 #elif (defined(CONFIG_MX28) || defined(CONFIG_MX6))
-       uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set);
+       uint32_t *setreg = &apbh_regs->hw_apbh_channel_ctrl_set;
        uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET;
 #endif
 
@@ -236,8 +234,6 @@ static int mxs_dma_reset(int channel)
  */
 static int mxs_dma_enable_irq(int channel, int enable)
 {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
 
        ret = mxs_dma_validate_chan(channel);
@@ -262,8 +258,6 @@ static int mxs_dma_enable_irq(int channel, int enable)
  */
 static int mxs_dma_ack_irq(int channel)
 {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
 
        ret = mxs_dma_validate_chan(channel);
@@ -296,6 +290,7 @@ static int mxs_dma_request(int channel)
        pchan->flags |= MXS_DMA_FLAGS_ALLOCATED;
        pchan->active_num = 0;
        pchan->pending_num = 0;
+       pchan->timeout = 10000000;
 
        INIT_LIST_HEAD(&pchan->active);
        INIT_LIST_HEAD(&pchan->done);
@@ -333,6 +328,44 @@ int mxs_dma_release(int channel)
        return 0;
 }
 
+/*
+ * Set the timeout for any DMA operation started with mxs_dma_go()
+ * The timeout value given is in milliseconds
+ */
+int mxs_dma_set_timeout(int channel, unsigned long timeout)
+{
+       int ret;
+       struct mxs_dma_chan *pchan;
+
+       ret = mxs_dma_validate_chan(channel);
+       if (ret)
+               return ret;
+
+       pchan = &mxs_dma_channels[channel];
+
+       if (pchan->flags & MXS_DMA_FLAGS_BUSY)
+               return -EBUSY;
+
+       if (timeout > ~0UL / 1000)
+               return -EINVAL;
+
+       pchan->timeout = timeout;
+       return 0;
+}
+
+unsigned long mxs_dma_get_timeout(int channel)
+{
+       int ret;
+       struct mxs_dma_chan *pchan;
+
+       ret = mxs_dma_validate_chan(channel);
+       if (ret)
+               return 0;
+
+       pchan = &mxs_dma_channels[channel];
+       return pchan->timeout;
+}
+
 /*
  * Allocate DMA descriptor
  */
@@ -499,8 +532,6 @@ static int mxs_dma_finish(int channel, struct list_head *head)
  */
 static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan)
 {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
        int ret;
 
        ret = mxs_dma_validate_chan(chan);
@@ -521,16 +552,25 @@ static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan)
  */
 int mxs_dma_go(int chan)
 {
-       uint32_t timeout = 10000000;
        int ret;
-
+       struct mxs_dma_chan *pchan;
        LIST_HEAD(tmp_desc_list);
 
+       ret = mxs_dma_validate_chan(chan);
+       if (ret)
+               return ret;
+
+       pchan = &mxs_dma_channels[chan];
+
        mxs_dma_enable_irq(chan, 1);
-       mxs_dma_enable(chan);
+       ret = mxs_dma_enable(chan);
+       if (ret) {
+               mxs_dma_enable_irq(chan, 0);
+               return ret;
+       }
 
        /* Wait for DMA to finish. */
-       ret = mxs_dma_wait_complete(timeout, chan);
+       ret = mxs_dma_wait_complete(pchan->timeout * 1000, chan);
 
        /* Clear out the descriptors we just ran. */
        mxs_dma_finish(chan, &tmp_desc_list);
@@ -571,9 +611,6 @@ void mxs_dma_circ_start(int chan, struct mxs_dma_desc *pdesc)
  */
 void mxs_dma_init(void)
 {
-       struct mxs_apbh_regs *apbh_regs =
-               (struct mxs_apbh_regs *)MXS_APBH_BASE;
-
        mxs_reset_block(&apbh_regs->hw_apbh_ctrl0_reg);
 
 #ifdef CONFIG_APBH_DMA_BURST8
index aa11f15423a4a7968462fc7569d7edbf8c72eeee..e035a7433366dda97a9249bce6d7d291369304e3 100644 (file)
@@ -9,14 +9,15 @@ ifndef CONFIG_SPL_BUILD
 obj-$(CONFIG_DM_GPIO)          += gpio-uclass.o
 endif
 
-obj-$(CONFIG_AT91_GPIO)        += at91_gpio.o
+obj-$(CONFIG_AM33XX_GPIO)      += am33xx_gpio.o
+obj-$(CONFIG_AT91_GPIO)                += at91_gpio.o
 obj-$(CONFIG_INTEL_ICH6_GPIO)  += intel_ich6_gpio.o
 obj-$(CONFIG_KIRKWOOD_GPIO)    += kw_gpio.o
-obj-$(CONFIG_KONA_GPIO)        += kona_gpio.o
+obj-$(CONFIG_KONA_GPIO)                += kona_gpio.o
 obj-$(CONFIG_MARVELL_GPIO)     += mvgpio.o
 obj-$(CONFIG_MARVELL_MFP)      += mvmfp.o
-obj-$(CONFIG_MXC_GPIO) += mxc_gpio.o
-obj-$(CONFIG_MXS_GPIO) += mxs_gpio.o
+obj-$(CONFIG_MXC_GPIO)         += mxc_gpio.o
+obj-$(CONFIG_MXS_GPIO)         += mxs_gpio.o
 obj-$(CONFIG_PCA953X)          += pca953x.o
 obj-$(CONFIG_PCA9698)          += pca9698.o
 obj-$(CONFIG_S5P)              += s5p_gpio.o
@@ -28,12 +29,12 @@ obj-$(CONFIG_DM644X_GPIO)   += da8xx_gpio.o
 obj-$(CONFIG_ALTERA_PIO)       += altera_pio.o
 obj-$(CONFIG_MPC83XX_GPIO)     += mpc83xx_gpio.o
 obj-$(CONFIG_SH_GPIO_PFC)      += sh_pfc.o
-obj-$(CONFIG_OMAP_GPIO)        += omap_gpio.o
+obj-$(CONFIG_OMAP_GPIO)                += omap_gpio.o
 obj-$(CONFIG_DB8500_GPIO)      += db8500_gpio.o
 obj-$(CONFIG_BCM2835_GPIO)     += bcm2835_gpio.o
 obj-$(CONFIG_S3C2440_GPIO)     += s3c2440_gpio.o
 obj-$(CONFIG_XILINX_GPIO)      += xilinx_gpio.o
-obj-$(CONFIG_ADI_GPIO2)        += adi_gpio2.o
+obj-$(CONFIG_ADI_GPIO2)                += adi_gpio2.o
 obj-$(CONFIG_TCA642X)          += tca642x.o
 oby-$(CONFIG_SX151X)           += sx151x.o
 obj-$(CONFIG_SUNXI_GPIO)       += sunxi_gpio.o
diff --git a/drivers/gpio/am33xx_gpio.c b/drivers/gpio/am33xx_gpio.c
new file mode 100644 (file)
index 0000000..4893d25
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <linux/sizes.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/gpio.h>
+
+struct gpio_regs {
+       unsigned int res1[0x134 / 4];
+       unsigned int oe;                /* 0x134 */
+       unsigned int datain;            /* 0x138 */
+       unsigned int res2[0x54 / 4];
+       unsigned int cleardataout;      /* 0x190 */
+       unsigned int setdataout;        /* 0x194 */
+};
+
+static const struct gpio_regs *gpio_base[] = {
+       (struct gpio_regs *)AM33XX_GPIO0_BASE,
+       (struct gpio_regs *)AM33XX_GPIO1_BASE,
+       (struct gpio_regs *)AM33XX_GPIO2_BASE,
+       (struct gpio_regs *)AM33XX_GPIO3_BASE,
+};
+
+static unsigned long gpio_map[ARRAY_SIZE(gpio_base)] __attribute__((section("data")));
+
+#define MAX_GPIO       (ARRAY_SIZE(gpio_base) * 32)
+
+int gpio_request(unsigned gpio, const char *name)
+{
+       if (gpio >= MAX_GPIO) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       if (test_and_set_bit(gpio, gpio_map))
+               return -EBUSY;
+       return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+       if (gpio >= MAX_GPIO) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       if (test_bit(gpio, gpio_map))
+               __clear_bit(gpio, gpio_map);
+       else
+               printf("ERROR: trying to free unclaimed GPIO %u\n", gpio);
+
+       return 0;
+}
+
+int gpio_set_value(unsigned gpio, int val)
+{
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       if (val)
+               writel(mask, &gpio_base[bank]->setdataout);
+       else
+               writel(mask, &gpio_base[bank]->cleardataout);
+       return 0;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       return (readl(&gpio_base[bank]->datain) & mask) != 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       writel(readl(&gpio_base[bank]->oe) | mask, &gpio_base[bank]->oe);
+       return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int val)
+{
+       int bank = gpio / 32;
+       int mask = 1 << (gpio % 32);
+
+       if (bank >= ARRAY_SIZE(gpio_base)) {
+               printf("ERROR: Invalid GPIO: %u (GPIO%u_%u)\n", gpio,
+                       gpio / 32, gpio % 32);
+               return -EINVAL;
+       }
+       gpio_set_value(gpio, val);
+       writel(readl(&gpio_base[bank]->oe) & ~mask, &gpio_base[bank]->oe);
+       return 0;
+}
index a69bbd2002e9f62c06f75cb1f1b4b755140eecc2..8ff82c5e62b5c1e62f03026a9979db5900170199 100644 (file)
@@ -190,6 +190,48 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...)
        return gpio_request(gpio, buf);
 }
 
+int gpio_request_one(unsigned int gpio, enum gpio_flags flags,
+               const char *label)
+{
+       int ret;
+
+       ret = gpio_request(gpio, label);
+       if (ret)
+               return ret;
+
+       if (flags == GPIOFLAG_INPUT)
+               gpio_direction_input(gpio);
+       else if (flags == GPIOFLAG_OUTPUT_INIT_LOW)
+               gpio_direction_output(gpio, 0);
+       else if (flags == GPIOFLAG_OUTPUT_INIT_HIGH)
+               gpio_direction_output(gpio, 1);
+
+       return ret;
+}
+
+int gpio_request_array(const struct gpio *gpios, int count)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < count; i++) {
+               ret = gpio_request_one(gpios[i].gpio, gpios[i].flags,
+                               gpios[i].label);
+               if (ret) {
+                       printf("Failed to request GPIO%d (%u of %u): %d\n",
+                               gpios[i].gpio, i, count, ret);
+                       goto error;
+               }
+       }
+       return 0;
+
+error:
+       while (--i >= 0)
+               gpio_free(gpios[i].gpio);
+
+       return ret;
+}
+
 int _dm_gpio_free(struct udevice *dev, uint offset)
 {
        struct gpio_dev_priv *uc_priv;
@@ -210,6 +252,17 @@ int _dm_gpio_free(struct udevice *dev, uint offset)
        return 0;
 }
 
+int gpio_free_array(const struct gpio *gpios, int count)
+{
+       int ret = 0;
+       int i;
+
+       for (i = 0; i < count; i++)
+               ret |= gpio_free(gpios[i].gpio);
+
+       return ret;
+}
+
 /**
  * gpio_free() - [COMPAT] Relinquish GPIO
  * gpio:       GPIO number
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
new file mode 100644 (file)
index 0000000..63b287c
--- /dev/null
@@ -0,0 +1,55 @@
+#include <common.h>
+#include <asm-generic/gpio.h>
+
+int gpio_request_one(unsigned int gpio, enum gpio_flags flags,
+               const char *label)
+{
+       int ret;
+
+       ret = gpio_request(gpio, label);
+       if (ret)
+               return ret;
+
+       if (flags == GPIOFLAG_INPUT)
+               gpio_direction_input(gpio);
+       else if (flags == GPIOFLAG_OUTPUT_INIT_LOW)
+               gpio_direction_output(gpio, 0);
+       else if (flags == GPIOFLAG_OUTPUT_INIT_HIGH)
+               gpio_direction_output(gpio, 1);
+
+       return ret;
+}
+
+int gpio_request_array(const struct gpio *gpios, int count)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < count; i++) {
+               ret = gpio_request_one(gpios[i].gpio, gpios[i].flags,
+                               gpios[i].label);
+               if (ret) {
+                       printf("Failed to request GPIO%d (%u of %u): %d\n",
+                               gpios[i].gpio, i, count, ret);
+                       goto error;
+               }
+       }
+       return 0;
+
+error:
+       while (--i >= 0)
+               gpio_free(gpios[i].gpio);
+
+       return ret;
+}
+
+int gpio_free_array(const struct gpio *gpios, int count)
+{
+       int ret = 0;
+       int i;
+
+       for (i = 0; i < count; i++)
+               ret |= gpio_free(gpios[i].gpio);
+
+       return ret;
+}
index 8bb9e39b7231e522f87eaf9612ad5abf383931e7..a46d33e8d91b49e5861681b7546082d8a27648ed 100644 (file)
@@ -31,7 +31,7 @@ struct mxc_bank_info {
 };
 
 #ifndef CONFIG_DM_GPIO
-#define GPIO_TO_PORT(n)                (n / 32)
+#define GPIO_TO_PORT(n)                ((n) / 32)
 
 /* GPIO port description */
 static unsigned long gpio_ports[] = {
@@ -58,8 +58,10 @@ static int mxc_gpio_direction(unsigned int gpio,
        struct gpio_regs *regs;
        u32 l;
 
-       if (port >= ARRAY_SIZE(gpio_ports))
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
                return -1;
+       }
 
        gpio &= 0x1f;
 
@@ -85,8 +87,10 @@ int gpio_set_value(unsigned gpio, int value)
        struct gpio_regs *regs;
        u32 l;
 
-       if (port >= ARRAY_SIZE(gpio_ports))
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
                return -1;
+       }
 
        gpio &= 0x1f;
 
@@ -108,28 +112,42 @@ int gpio_get_value(unsigned gpio)
        struct gpio_regs *regs;
        u32 val;
 
-       if (port >= ARRAY_SIZE(gpio_ports))
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
                return -1;
+       }
 
        gpio &= 0x1f;
 
        regs = (struct gpio_regs *)gpio_ports[port];
 
-       val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
-
+       if (readl(&regs->gpio_dir) & (1 << gpio)) {
+               printf("WARNING: Reading status of output GPIO_%d_%d\n",
+                       port - GPIO_TO_PORT(0), gpio);
+               val = (readl(&regs->gpio_dr) >> gpio) & 0x01;
+       } else {
+               val = (readl(&regs->gpio_psr) >> gpio) & 0x01;
+       }
        return val;
 }
 
 int gpio_request(unsigned gpio, const char *label)
 {
        unsigned int port = GPIO_TO_PORT(gpio);
-       if (port >= ARRAY_SIZE(gpio_ports))
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
                return -1;
+       }
        return 0;
 }
 
 int gpio_free(unsigned gpio)
 {
+       unsigned int port = GPIO_TO_PORT(gpio);
+       if (port >= ARRAY_SIZE(gpio_ports)) {
+               printf("%s: Invalid GPIO %d\n", __func__, gpio);
+               return -1;
+       }
        return 0;
 }
 
index 202ea5d67940ece1c555568794a7cfd343f0fc30..8babe12159fee027a7c24559141aba7e4fe52756 100644 (file)
@@ -20,3 +20,17 @@ config SYS_I2C_UNIPHIER_F
        help
          Support for Panasonic UniPhier FIFO-builtin I2C controller driver.
          This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs.
+menuconfig SYS_I2C
+       bool "I2C device support"
+
+if SYS_I2C
+
+config HARD_I2C
+       bool
+
+config SYS_I2C_MXC
+       bool "Freescale i.MX I2C controller"
+       select HARD_I2C
+       select I2C_QUIRK_REG if FSL_LSCH3 || LS102XA
+
+endif
index 36433a74f85f37e2f7877856853328d3d38527cf..df3885041e5cd129802fceb1efe08831b1b176ad 100644 (file)
@@ -89,7 +89,7 @@ struct fsl_iim {
        u32 sdat;
        u32 prev;
        u32 srev;
-       u32 prg_p;
+       u32 preg_p;
        u32 scs[0x1f5];
        struct {
                u32 word[0x100];
@@ -169,7 +169,7 @@ static void direct_access(struct fsl_iim *regs, u32 bank, u32 word, u32 bit,
        iim_write32(&regs->ua, bank << 3 | word >> 5);
        iim_write32(&regs->la, (word << 3 | bit) & 0xff);
        if (fctl == FCTL_PRG)
-               iim_write32(&regs->prg_p, 0xaa);
+               iim_write32(&regs->preg_p, 0xaa);
        iim_setbits32(&regs->fctl, fctl);
        while (iim_read32(&regs->stat) & STAT_BUSY)
                udelay(20);
@@ -208,7 +208,7 @@ static int prog_bit(struct fsl_iim *regs, u32 bank, u32 word, u32 bit)
 
        clear_status(regs);
        direct_access(regs, bank, word, bit, FCTL_PRG, &stat, &err);
-       iim_write32(&regs->prg_p, 0x00);
+       iim_write32(&regs->preg_p, 0x00);
 
        if (err & ERR_PRGE) {
                puts("fsl_iim fuse_prog(): Program error\n");
index 7ba85a2b62c45b5f968dbddc1994d7f174163e9a..b52100c2c51c21c19087b085257fda95752ef9e3 100644 (file)
@@ -1,9 +1,29 @@
 menu "MMC Host controller Support"
 
+config MMC
+       bool
+
+config GENERIC_MMC
+       bool
+       select MMC
+
 config SH_SDHI
        bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
        depends on RMOBILE
        help
          Support for the on-chip SDHI host controller on SuperH/Renesas ARM SoCs platform
 
+config FSL_ESDHC
+       bool "Freescale ESDHC controller"
+       select GENERIC_MMC
+
+config FSL_USDHC
+       bool "Support USDHC"
+       depends on MX6Q
+       depends on FSL_ESDHC
+
+config SUPPORT_EMMC_BOOT
+       bool "Support boot from eMMC"
+       depends on MMC
+
 endmenu
index c55eb28217bc5920c3137016dc71b8a6cd58b4b4..57efda23e1f3e61a99da0d944b1e2f7cdf60f929 100644 (file)
@@ -118,57 +118,69 @@ static void
 esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
 {
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
        uint blocks;
        char *buffer;
        uint databuf;
        uint size;
-       uint irqstat;
        uint timeout;
+       int wml = esdhc_read32(&regs->wml);
 
        if (data->flags & MMC_DATA_READ) {
+               wml &= WML_RD_WML_MASK;
                blocks = data->blocks;
                buffer = data->dest;
                while (blocks) {
                        timeout = PIO_TIMEOUT;
                        size = data->blocksize;
-                       irqstat = esdhc_read32(&regs->irqstat);
-                       while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)
-                               && --timeout);
-                       if (timeout <= 0) {
-                               printf("\nData Read Failed in PIO Mode.");
-                               return;
-                       }
-                       while (size && (!(irqstat & IRQSTAT_TC))) {
-                               udelay(100); /* Wait before last byte transfer complete */
-                               irqstat = esdhc_read32(&regs->irqstat);
-                               databuf = in_le32(&regs->datport);
-                               *((uint *)buffer) = databuf;
-                               buffer += 4;
-                               size -= 4;
+                       while (size &&
+                               !(esdhc_read32(&regs->irqstat) & IRQSTAT_TC)) {
+                               int i;
+                               u32 prsstat;
+
+                               while (!((prsstat = esdhc_read32(&regs->prsstat)) &
+                                               PRSSTAT_BREN) && --timeout)
+                                       /* NOP */;
+                               if (!(prsstat & PRSSTAT_BREN)) {
+                                       printf("%s: Data Read Failed in PIO Mode\n",
+                                               __func__);
+                                       return;
+                               }
+                               for (i = 0; i < wml && size; i++) {
+                                       databuf = in_le32(&regs->datport);
+                                       memcpy(buffer, &databuf, sizeof(databuf));
+                                       buffer += 4;
+                                       size -= 4;
+                               }
                        }
                        blocks--;
                }
        } else {
+               wml = (wml & WML_WR_WML_MASK) >> 16;
                blocks = data->blocks;
-               buffer = (char *)data->src;
+               buffer = (char *)data->src; /* cast away 'const' */
                while (blocks) {
                        timeout = PIO_TIMEOUT;
                        size = data->blocksize;
-                       irqstat = esdhc_read32(&regs->irqstat);
-                       while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)
-                               && --timeout);
-                       if (timeout <= 0) {
-                               printf("\nData Write Failed in PIO Mode.");
-                               return;
-                       }
-                       while (size && (!(irqstat & IRQSTAT_TC))) {
-                               udelay(100); /* Wait before last byte transfer complete */
-                               databuf = *((uint *)buffer);
-                               buffer += 4;
-                               size -= 4;
-                               irqstat = esdhc_read32(&regs->irqstat);
-                               out_le32(&regs->datport, databuf);
+                       while (size &&
+                               !(esdhc_read32(&regs->irqstat) & IRQSTAT_TC)) {
+                               int i;
+                               u32 prsstat;
+
+                               while (!((prsstat = esdhc_read32(&regs->prsstat)) &
+                                               PRSSTAT_BWEN) && --timeout)
+                                       /* NOP */;
+                               if (!(prsstat & PRSSTAT_BWEN)) {
+                                       printf("%s: Data Write Failed in PIO Mode\n",
+                                               __func__);
+                                       return;
+                               }
+                               for (i = 0; i < wml && size; i++) {
+                                       memcpy(&databuf, buffer, sizeof(databuf));
+                                       out_le32(&regs->datport, databuf);
+                                       buffer += 4;
+                                       size -= 4;
+                               }
                        }
                        blocks--;
                }
@@ -180,11 +192,10 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 {
        int timeout;
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
-
+       struct fsl_esdhc *regs = cfg->esdhc_base;
        uint wml_value;
 
-       wml_value = data->blocksize/4;
+       wml_value = data->blocksize / 4;
 
        if (data->flags & MMC_DATA_READ) {
                if (wml_value > WML_RD_WML_MAX)
@@ -203,10 +214,12 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
                if (wml_value > WML_WR_WML_MAX)
                        wml_value = WML_WR_WML_MAX_VAL;
                if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
-                       printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
-                       return TIMEOUT;
+                       printf("The SD card is locked. Can not write to a locked card.\n");
+                       return UNUSABLE_ERR;
                }
 
+               flush_dcache_range((unsigned long)data->src,
+                               (unsigned long)data->src + data->blocks * data->blocksize);
                esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
                                        wml_value << 16);
 #ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
@@ -214,7 +227,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 #endif
        }
 
-       esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
+       esdhc_write32(&regs->blkattr, (data->blocks << 16) | data->blocksize);
 
        /* Calculate the timeout period for data transactions */
        /*
@@ -236,8 +249,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
 
        if (timeout > 14)
                timeout = 14;
-
-       if (timeout < 0)
+       else if (timeout < 0)
                timeout = 0;
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC_A001
@@ -276,24 +288,32 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        uint    xfertyp;
        uint    irqstat;
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       volatile struct fsl_esdhc *regs = cfg->esdhc_base;
+       unsigned long start;
 
 #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
        if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
                return 0;
 #endif
-
        esdhc_write32(&regs->irqstat, -1);
 
        sync();
 
+       start = get_timer_masked();
        /* Wait for the bus to be idle */
        while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
-                       (esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
-               ;
+               (esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB)) {
+               if (get_timer(start) > CONFIG_SYS_HZ) {
+                       printf("%s: Timeout waiting for bus idle\n", __func__);
+                       return TIMEOUT;
+               }
+       }
 
-       while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
-               ;
+       start = get_timer_masked();
+       while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA) {
+               if (get_timer(start) > CONFIG_SYS_HZ)
+                       return TIMEOUT;
+       }
 
        /* Wait at least 8 SD clock cycles before the next command */
        /*
@@ -305,7 +325,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        /* Set up for a data transfer if we have one */
        if (data) {
                err = esdhc_setup_data(mmc, data);
-               if(err)
+               if (err)
                        return err;
        }
 
@@ -319,15 +339,26 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        esdhc_write32(&regs->cmdarg, cmd->cmdarg);
 #if defined(CONFIG_FSL_USDHC)
        esdhc_write32(&regs->mixctrl,
-       (esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F));
+       (esdhc_read32(&regs->mixctrl) & ~0x7f) | (xfertyp & 0x7F));
        esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
 #else
        esdhc_write32(&regs->xfertyp, xfertyp);
 #endif
 
+       /* Mask all irqs */
+       esdhc_write32(&regs->irqsigen, 0);
+
+       start = get_timer_masked();
        /* Wait for the command to complete */
-       while (!(esdhc_read32(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
-               ;
+       while (!(esdhc_read32(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE))) {
+               if (get_timer(start) > CONFIG_SYS_HZ) {
+                       printf("%s: Timeout waiting for cmd completion\n", __func__);
+                       return TIMEOUT;
+               }
+       }
+
+       if (data && (data->flags & MMC_DATA_READ))
+               check_and_invalidate_dcache_range(cmd, data);
 
        irqstat = esdhc_read32(&regs->irqstat);
 
@@ -415,7 +446,7 @@ out:
                }
        }
 
-       esdhc_write32(&regs->irqstat, -1);
+       esdhc_write32(&regs->irqstat, irqstat);
 
        return err;
 }
@@ -424,7 +455,7 @@ static void set_sysctl(struct mmc *mmc, uint clock)
 {
        int div, pre_div;
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       volatile struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       volatile struct fsl_esdhc *regs = cfg->esdhc_base;
        int sdhc_clk = cfg->sdhc_clk;
        uint clk;
 
@@ -461,7 +492,7 @@ static void set_sysctl(struct mmc *mmc, uint clock)
 static void esdhc_set_ios(struct mmc *mmc)
 {
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
 
        /* Set the clock speed */
        set_sysctl(mmc, mmc->clock);
@@ -479,7 +510,7 @@ static void esdhc_set_ios(struct mmc *mmc)
 static int esdhc_init(struct mmc *mmc)
 {
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
        int timeout = 1000;
 
        /* Reset the entire host controller */
@@ -514,7 +545,7 @@ static int esdhc_init(struct mmc *mmc)
 static int esdhc_getcd(struct mmc *mmc)
 {
        struct fsl_esdhc_cfg *cfg = mmc->priv;
-       struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
+       struct fsl_esdhc *regs = cfg->esdhc_base;
        int timeout = 1000;
 
 #ifdef CONFIG_ESDHC_DETECT_QUIRK
@@ -555,7 +586,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
        u32 caps, voltage_caps;
 
        if (!cfg)
-               return -1;
+               return -EINVAL;
 
        regs = (struct fsl_esdhc *)cfg->esdhc_base;
 
@@ -597,7 +628,7 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
 #endif
        if ((cfg->cfg.voltages & voltage_caps) == 0) {
                printf("voltage not supported by controller\n");
-               return -1;
+               return -EINVAL;
        }
 
        cfg->cfg.host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
@@ -633,8 +664,10 @@ int fsl_esdhc_mmc_init(bd_t *bis)
 {
        struct fsl_esdhc_cfg *cfg;
 
-       cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
-       cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
+       cfg = kzalloc(sizeof(struct fsl_esdhc_cfg), GFP_KERNEL);
+       if (!cfg)
+               return -ENOMEM;
+       cfg->esdhc_base = (void __iomem *)CONFIG_SYS_FSL_ESDHC_ADDR;
        cfg->sdhc_clk = gd->arch.sdhc_clk;
        return fsl_esdhc_initialize(bis, cfg);
 }
index b8039cd092abd43a14022f0a1e7a646198c30aa6..85e9509ed19374115421bcc6fc5ba10c380f0a24 100644 (file)
@@ -324,8 +324,7 @@ static int sd_send_op_cond(struct mmc *mmc)
 
                udelay(1000);
        } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
-
-       if (timeout <= 0)
+       if (!(cmd.response[0] & OCR_BUSY))
                return UNUSABLE_ERR;
 
        if (mmc->version != SD_VERSION_2)
@@ -383,7 +382,7 @@ static int mmc_send_op_cond(struct mmc *mmc)
        /* Some cards seem to need this */
        mmc_go_idle(mmc);
 
-       /* Asking to the card its capabilities */
+       /* Asking to the card its capabilities */
        mmc->op_cond_pending = 1;
        for (i = 0; i < 2; i++) {
                err = mmc_send_op_cond_iter(mmc, &cmd, i != 0);
@@ -411,9 +410,13 @@ static int mmc_complete_op_cond(struct mmc *mmc)
                if (err)
                        return err;
                if (get_timer(start) > timeout)
-                       return UNUSABLE_ERR;
+                       break;
                udelay(100);
        } while (!(mmc->op_cond_response & OCR_BUSY));
+       if (!(mmc->op_cond_response & OCR_BUSY)) {
+               debug("%s: timeout\n", __func__);
+               return UNUSABLE_ERR;
+       }
 
        if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
                cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
index 2fa4eeef441f16b552e0742571dd6c625cf85cd5..6f74299adbdad53c885fc50977530e9f02f7fa2f 100644 (file)
@@ -87,7 +87,8 @@ static int mxsmmc_send_cmd_pio(struct mxsmmc_priv *priv, struct mmc_data *data)
        return timeout ? 0 : COMM_ERR;
 }
 
-static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
+static int mxsmmc_send_cmd_dma(struct mmc *mmc, struct mxsmmc_priv *priv,
+                       struct mmc_data *data)
 {
        uint32_t data_count = data->blocksize * data->blocks;
        int dmach;
@@ -95,6 +96,9 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
        void *addr;
        unsigned int flags;
        struct bounce_buffer bbstate;
+       unsigned long xfer_rate = (mmc->clock ?: 400000) * mmc->bus_width;
+       unsigned long dma_timeout = data_count * 8 /
+               DIV_ROUND_UP(xfer_rate, 1000);
 
        memset(desc, 0, sizeof(struct mxs_dma_desc));
        desc->address = (dma_addr_t)desc;
@@ -118,6 +122,8 @@ static int mxsmmc_send_cmd_dma(struct mxsmmc_priv *priv, struct mmc_data *data)
 
        dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + priv->id;
        mxs_dma_desc_append(dmach, priv->desc);
+       /* set DMA timeout adding 250ms for min timeout according to SD spec. */
+       mxs_dma_set_timeout(dmach, dma_timeout + 250);
        if (mxs_dma_go(dmach)) {
                bounce_buffer_stop(&bbstate);
                return COMM_ERR;
@@ -140,23 +146,20 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        uint32_t reg;
        int timeout;
        uint32_t ctrl0;
+       const uint32_t busy_stat = SSP_STATUS_BUSY | SSP_STATUS_DATA_BUSY |
+               SSP_STATUS_CMD_BUSY;
        int ret;
 
        debug("MMC%d: CMD%d\n", mmc->block_dev.dev, cmd->cmdidx);
 
        /* Check bus busy */
        timeout = MXSMMC_MAX_TIMEOUT;
-       while (--timeout) {
-               udelay(1000);
-               reg = readl(&ssp_regs->hw_ssp_status);
-               if (!(reg &
-                       (SSP_STATUS_BUSY | SSP_STATUS_DATA_BUSY |
-                       SSP_STATUS_CMD_BUSY))) {
+       while ((reg = readl(&ssp_regs->hw_ssp_status)) & busy_stat) {
+               if (timeout-- <= 0)
                        break;
-               }
+               udelay(1000);
        }
-
-       if (!timeout) {
+       if (reg & busy_stat && readl(&ssp_regs->hw_ssp_status) & busy_stat) {
                printf("MMC%d: Bus busy timeout!\n", mmc->block_dev.dev);
                return TIMEOUT;
        }
@@ -240,8 +243,8 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
                if (!(reg & SSP_STATUS_CMD_BUSY))
                        break;
        }
-
-       if (!timeout) {
+       if ((reg & SSP_STATUS_CMD_BUSY) &&
+               (readl(&ssp_regs->hw_ssp_status) & SSP_STATUS_CMD_BUSY)) {
                printf("MMC%d: Command %d busy\n",
                        mmc->block_dev.dev, cmd->cmdidx);
                return TIMEOUT;
@@ -277,13 +280,12 @@ mxsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
        if (data->blocksize * data->blocks < MXSMMC_SMALL_TRANSFER) {
                ret = mxsmmc_send_cmd_pio(priv, data);
                if (ret) {
-                       printf("MMC%d: Data timeout with command %d "
-                               "(status 0x%08x)!\n",
+                       printf("MMC%d: Data timeout with command %d (status 0x%08x)!\n",
                                mmc->block_dev.dev, cmd->cmdidx, reg);
                        return ret;
                }
        } else {
-               ret = mxsmmc_send_cmd_dma(priv, data);
+               ret = mxsmmc_send_cmd_dma(mmc, priv, data);
                if (ret) {
                        printf("MMC%d: DMA transfer failed\n",
                                mmc->block_dev.dev);
@@ -372,27 +374,27 @@ static const struct mmc_ops mxsmmc_ops = {
 
 int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
 {
-       struct mmc *mmc = NULL;
-       struct mxsmmc_priv *priv = NULL;
+       struct mmc *mmc;
+       struct mxsmmc_priv *priv;
        int ret;
        const unsigned int mxsmmc_clk_id = mxs_ssp_clock_by_bus(id);
 
        if (!mxs_ssp_bus_id_valid(id))
                return -ENODEV;
 
-       priv = malloc(sizeof(struct mxsmmc_priv));
+       priv = calloc(sizeof(struct mxsmmc_priv), 1);
        if (!priv)
                return -ENOMEM;
 
        priv->desc = mxs_dma_desc_alloc();
        if (!priv->desc) {
-               free(priv);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto free_priv;
        }
 
        ret = mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + id);
        if (ret)
-               return ret;
+               goto free_priv;
 
        priv->mmc_is_wp = wp;
        priv->mmc_cd = cd;
@@ -420,9 +422,14 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
 
        mmc = mmc_create(&priv->cfg, priv);
        if (mmc == NULL) {
-               mxs_dma_desc_free(priv->desc);
-               free(priv);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto free_dma;
        }
        return 0;
+
+free_dma:
+       mxs_dma_desc_free(priv->desc);
+free_priv:
+       free(priv);
+       return ret;
 }
index dc725cb5b0d83428a6d8e6b65b180aa413f08c95..813b90946cacd4a3ad47c9c457cb1958a5696235 100644 (file)
@@ -125,7 +125,7 @@ static void omap5_pbias_config(struct mmc *mmc)
 }
 #endif
 
-static unsigned char mmc_board_init(struct mmc *mmc)
+static void mmc_board_init(struct mmc *mmc)
 {
 #if defined(CONFIG_OMAP34XX)
        t2_t *t2_base = (t2_t *)T2_BASE;
@@ -173,8 +173,6 @@ static unsigned char mmc_board_init(struct mmc *mmc)
        if (mmc->block_dev.dev == 0)
                omap5_pbias_config(mmc);
 #endif
-
-       return 0;
 }
 
 void mmc_init_stream(struct hsmmc *mmc_base)
@@ -186,21 +184,25 @@ void mmc_init_stream(struct hsmmc *mmc_base)
        writel(MMC_CMD0, &mmc_base->cmd);
        start = get_timer(0);
        while (!(readl(&mmc_base->stat) & CC_MASK)) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for cc!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!(readl(&mmc_base->stat) & CC_MASK)) {
+               printf("%s: timeout waiting for cc!\n", __func__);
+               return;
        }
-       writel(CC_MASK, &mmc_base->stat)
-               ;
-       writel(MMC_CMD0, &mmc_base->cmd)
-               ;
+
+       writel(CC_MASK, &mmc_base->stat);
+       writel(MMC_CMD0, &mmc_base->cmd);
+
        start = get_timer(0);
        while (!(readl(&mmc_base->stat) & CC_MASK)) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for cc2!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!(readl(&mmc_base->stat) & CC_MASK)) {
+               printf("%s: timeout waiting for cc2!\n", __func__);
+               return;
        }
        writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
 }
@@ -208,31 +210,35 @@ void mmc_init_stream(struct hsmmc *mmc_base)
 
 static int omap_hsmmc_init_setup(struct mmc *mmc)
 {
-       struct hsmmc *mmc_base;
+       struct omap_hsmmc_data *priv_data = mmc->priv;
+       struct hsmmc *mmc_base = priv_data->base_addr;
        unsigned int reg_val;
        unsigned int dsor;
        ulong start;
 
-       mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
        mmc_board_init(mmc);
 
        writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
                &mmc_base->sysconfig);
        start = get_timer(0);
        while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for cc2!\n", __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysstatus) & RESETDONE) == 0) {
+               printf("%s: timeout %08x waiting for softreset done!\n", __func__,
+                       readl(&mmc_base->sysstatus));
+               return TIMEOUT;
        }
        writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
        start = get_timer(0);
-       while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for softresetall!\n",
-                               __func__);
-                       return TIMEOUT;
-               }
+       while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0) {
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0) {
+               printf("%s: timeout waiting for softresetall!\n", __func__);
+               return TIMEOUT;
        }
        writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
        writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
@@ -251,10 +257,12 @@ static int omap_hsmmc_init_setup(struct mmc *mmc)
                (dsor << CLKD_OFFSET) | ICE_OSCILLATE);
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for ics!\n", __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+               printf("%s: timeout waiting for ics!\n", __func__);
+               return TIMEOUT;
        }
        writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
 
@@ -307,38 +315,41 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
 #endif
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & bit) != 0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for sysctl %x to clear\n",
-                               __func__, bit);
-                       return;
-               }
+               if (get_timer(0) - start > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & bit) != 0) {
+               printf("%s: timedout waiting for sysctl %x to clear\n", __func__, bit);
+               return;
        }
 }
 
 static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
                        struct mmc_data *data)
 {
-       struct hsmmc *mmc_base;
+       struct omap_hsmmc_data *priv_data = mmc->priv;
+       struct hsmmc *mmc_base = priv_data->base_addr;
        unsigned int flags, mmc_stat;
        ulong start;
 
-       mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
        start = get_timer(0);
        while ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting on cmd inhibit to clear\n",
-                                       __func__);
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->pstate) & (DATI_MASK | CMDI_MASK)) != 0) {
+               printf("%s: timeout waiting on cmd inhibit to clear\n", __func__);
+               return TIMEOUT;
        }
        writel(0xFFFFFFFF, &mmc_base->stat);
        start = get_timer(0);
        while (readl(&mmc_base->stat)) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for STAT (%x) to clear\n",
-                               __func__, readl(&mmc_base->stat));
-                       return TIMEOUT;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (readl(&mmc_base->stat)) {
+               printf("%s: timeout waiting for stat!\n", __func__);
+               return TIMEOUT;
        }
        /*
         * CMDREG
@@ -397,13 +408,14 @@ static int omap_hsmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
        writel((cmd->cmdidx << 24) | flags, &mmc_base->cmd);
 
        start = get_timer(0);
-       do {
-               mmc_stat = readl(&mmc_base->stat);
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s : timeout: No status update\n", __func__);
-                       return TIMEOUT;
-               }
-       } while (!mmc_stat);
+       while (!(mmc_stat = readl(&mmc_base->stat))) {
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if (!mmc_stat) {
+               printf("%s : timeout: No status update\n", __func__);
+               return TIMEOUT;
+       }
 
        if ((mmc_stat & IE_CTO) != 0) {
                mmc_reset_controller_fsm(mmc_base, SYSCTL_SRC);
@@ -450,14 +462,15 @@ static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size)
 
        while (size) {
                ulong start = get_timer(0);
-               do {
-                       mmc_stat = readl(&mmc_base->stat);
-                       if (get_timer(0) - start > MAX_RETRY_MS) {
-                               printf("%s: timedout waiting for status!\n",
-                                               __func__);
-                               return TIMEOUT;
-                       }
-               } while (mmc_stat == 0);
+
+               while (!(mmc_stat = readl(&mmc_base->stat))) {
+                       if (get_timer(start) > MAX_RETRY_MS)
+                               break;
+               }
+               if (!mmc_stat) {
+                       printf("%s: timeout waiting for status!\n", __func__);
+                       return TIMEOUT;
+               }
 
                if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
                        mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
@@ -505,14 +518,15 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
 
        while (size) {
                ulong start = get_timer(0);
-               do {
-                       mmc_stat = readl(&mmc_base->stat);
-                       if (get_timer(0) - start > MAX_RETRY_MS) {
-                               printf("%s: timedout waiting for status!\n",
-                                               __func__);
-                               return TIMEOUT;
-                       }
-               } while (mmc_stat == 0);
+
+               while (!(mmc_stat = readl(&mmc_base->stat))) {
+                       if (get_timer(start) > MAX_RETRY_MS)
+                               break;
+               }
+               if (!mmc_stat) {
+                       printf("%s: timeout waiting for status!\n", __func__);
+                       return TIMEOUT;
+               }
 
                if ((mmc_stat & (IE_DTO | IE_DCRC | IE_DEB)) != 0)
                        mmc_reset_controller_fsm(mmc_base, SYSCTL_SRD);
@@ -547,11 +561,11 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
 
 static void omap_hsmmc_set_ios(struct mmc *mmc)
 {
-       struct hsmmc *mmc_base;
+       struct omap_hsmmc_data *priv_data = mmc->priv;
+       struct hsmmc *mmc_base = priv_data->base_addr;
        unsigned int dsor = 0;
        ulong start;
 
-       mmc_base = ((struct omap_hsmmc_data *)mmc->priv)->base_addr;
        /* configue bus width */
        switch (mmc->bus_width) {
        case 8:
@@ -591,10 +605,12 @@ static void omap_hsmmc_set_ios(struct mmc *mmc)
 
        start = get_timer(0);
        while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
-               if (get_timer(0) - start > MAX_RETRY_MS) {
-                       printf("%s: timedout waiting for ics!\n", __func__);
-                       return;
-               }
+               if (get_timer(start) > MAX_RETRY_MS)
+                       break;
+       }
+       if ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) {
+               printf("%s: timeout waiting for ics!\n", __func__);
+               return;
        }
        writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
 }
@@ -642,21 +658,22 @@ static const struct mmc_ops omap_hsmmc_ops = {
 int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                int wp_gpio)
 {
+       int ret;
        struct mmc *mmc;
        struct omap_hsmmc_data *priv_data;
        struct mmc_config *cfg;
        uint host_caps_val;
 
-       priv_data = malloc(sizeof(*priv_data));
+       priv_data = calloc(sizeof(*priv_data), 1);
        if (priv_data == NULL)
-               return -1;
+               return -ENOMEM;
 
        host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
                             MMC_MODE_HC;
 
        switch (dev_index) {
        case 0:
-               priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
+               base_addr = OMAP_HSMMC1_BASE;
                break;
 #ifdef OMAP_HSMMC2_BASE
        case 1:
@@ -679,8 +696,9 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                break;
 #endif
        default:
-               priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE;
-               return 1;
+               printf("Invalid MMC device index: %d\n", dev_index);
+               ret = 1;
+               goto out;
        }
 #ifdef OMAP_HSMMC_USE_GPIO
        /* on error gpio values are set to -1, which is what we want */
@@ -720,8 +738,14 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
                cfg->b_max = 1;
 #endif
        mmc = mmc_create(cfg, priv_data);
-       if (mmc == NULL)
-               return -1;
+       if (mmc == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
 
        return 0;
+
+out:
+       free(priv_data);
+       return ret;
 }
index 415ab4eba9dd71a8f6c103a5321a709fed4f28cf..5b56f11e93497103392146fb1306b264628ec9c0 100644 (file)
@@ -1 +1,21 @@
+menuconfig NOR_FLASH
+       bool "NOR flash support"
+
+if NOR_FLASH
+
+config CONFIG_FLASH_CFI_DRIVER
+       bool "CFI flash driver"
+
+endif
+
+config SYS_NO_FLASH
+       bool
+       default y
+       depends on !NOR_FLASH
+
+config MTD_PARTITIONS
+       bool "Support MTD partition tables"
+       depends on MTD_DEVICE
+       default y
+
 source "drivers/mtd/nand/Kconfig"
index c24221499bfb6cd47f272cd5e71839d7296cf4ea..ebbc2d4a5668a768770f9a24ceb0843ce4fa598b 100644 (file)
@@ -1,4 +1,10 @@
-menu "NAND Device Support"
+menuconfig NAND
+       bool "NAND Device Support"
+
+if NAND
+
+config SYS_NAND_USE_FLASH_BBT
+       bool "Use a flash based bad block table"
 
 config SYS_NAND_SELF_INIT
        bool
@@ -46,4 +52,23 @@ config SPL_NAND_DENALI
 
 endif
 
-endmenu
+config NAND_MXC
+       bool "Support Freescale i.MX NAND controller"
+       select SYS_NAND_SELF_INIT if SPL
+       help
+         Enable support for the Freescale NAND controller found on
+         i.MX processors.
+
+config NAND_MXS
+       bool "Support Freescale GPMI NAND controller"
+       select SYS_NAND_SELF_INIT if SPL
+       help
+         Enable support for the Freescale GPMI NAND controller found
+         on i.MX28 and i.MX6 processors.
+
+config NAND_MXS_NO_BBM_SWAP
+       bool "disable bad block mark swapping"
+       depends on NAND_MXS && MX6
+       select SYS_NAND_USE_FLASH_BBT
+
+endif
index 7a064ab1bf945a2e5724ce9a9bf4e6ad403e1c81..4125a4cd1afd4268cb65a6275217f65b37c63bfd 100644 (file)
@@ -12,6 +12,7 @@
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
+//#define DEBUG
 
 #include <common.h>
 #include <linux/mtd/mtd.h>
 
 #define        MXS_NAND_COMMAND_BUFFER_SIZE            32
 
+/* BCH timeout in microseconds */
 #define        MXS_NAND_BCH_TIMEOUT                    10000
 
+static struct bch_regs *bch_regs = (void *)BCH_BASE_ADDRESS;
+static struct gpmi_regs *gpmi_regs = (void *)GPMI_BASE_ADDRESS;
 struct mxs_nand_info {
        int             cur_chip;
 
@@ -67,6 +71,109 @@ struct mxs_nand_info {
        uint32_t                desc_index;
 };
 
+#ifdef DEBUG
+#define dump_reg(b, r) __dump_reg(&b->r, #r)
+static inline void __dump_reg(void *addr, const char *name)
+{
+       printf("%16s[%p]=%08x\n", name, addr, readl(addr));
+}
+
+#define dump_bch_reg(n) __dump_reg(&bch_regs->hw_bch_##n, #n)
+#define dump_gpmi_reg(n) __dump_reg(&gpmi_regs->hw_gpmi_##n, #n)
+static inline void dump_regs(void)
+{
+       printf("BCH:\n");
+       dump_bch_reg(ctrl);
+       dump_bch_reg(status0);
+       dump_bch_reg(mode);
+       dump_bch_reg(debug0);
+       dump_bch_reg(dbgkesread);
+       dump_bch_reg(dbgcsferead);
+       dump_bch_reg(dbgsyndegread);
+       dump_bch_reg(dbgahbmread);
+       dump_bch_reg(blockname);
+       dump_bch_reg(version);
+
+       printf("\nGPMI:\n");
+       dump_gpmi_reg(ctrl0);
+       dump_gpmi_reg(eccctrl);
+       dump_gpmi_reg(ecccount);
+       dump_gpmi_reg(payload);
+       dump_gpmi_reg(auxiliary);
+       dump_gpmi_reg(ctrl1);
+       dump_gpmi_reg(data);
+       dump_gpmi_reg(stat);
+       dump_gpmi_reg(debug);
+       dump_gpmi_reg(version);
+       dump_gpmi_reg(debug2);
+       dump_gpmi_reg(debug3);
+}
+
+static inline int dbg_addr(void *addr)
+{
+       if (((unsigned long)addr & ~0xfff) == BCH_BASE_ADDRESS)
+               return 1;
+       return 1;
+}
+
+static inline u32 mxs_readl(void *addr,
+                       const char *fn, int ln)
+{
+       u32 val = readl(addr);
+       static void *last_addr;
+       static u32 last_val;
+
+       if (!dbg_addr(addr))
+               return val;
+
+       if (addr != last_addr || last_val != val) {
+               printf("%s@%d: Read %08x from %p\n", fn, ln, val, addr);
+               last_addr = addr;
+               last_val = val;
+       }
+       return val;
+}
+
+static inline void mxs_writel(u32 val, void *addr,
+                       const char *fn, int ln)
+{
+       if (dbg_addr(addr))
+               printf("%s@%d: Writing %08x to %p...", fn, ln, val, addr);
+       writel(val, addr);
+       if (dbg_addr(addr))
+               printf(" result: %08x\n", readl(addr));
+}
+
+#undef readl
+#define readl(a) mxs_readl(a, __func__, __LINE__)
+
+#undef writel
+#define writel(v, a) mxs_writel(v, a, __func__, __LINE__)
+static inline void memdump(const void *addr, size_t len)
+{
+       const char *buf = addr;
+       int i;
+
+       for (i = 0; i < len; i++) {
+               if (i % 16 == 0) {
+                       if (i > 0)
+                               printf("\n");
+                       printf("%p:", &buf[i]);
+               }
+               printf(" %02x", buf[i]);
+       }
+       printf("\n");
+}
+#else
+static inline void memdump(void *addr, size_t len)
+{
+}
+
+static inline void dump_regs(void)
+{
+}
+#endif
+
 struct nand_ecclayout fake_ecc_layout;
 
 /*
@@ -128,12 +235,13 @@ static void mxs_nand_return_dma_descs(struct mxs_nand_info *info)
        info->desc_index = 0;
 }
 
-static uint32_t mxs_nand_ecc_chunk_cnt(uint32_t page_data_size)
+static uint32_t mxs_nand_ecc_chunk_cnt(struct mtd_info *mtd)
 {
-       return page_data_size / MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
+       struct nand_chip *nand = mtd->priv;
+       return mtd->writesize / nand->ecc.size;
 }
 
-static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength)
+static inline uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength)
 {
        return ecc_strength * 13;
 }
@@ -143,6 +251,27 @@ static uint32_t mxs_nand_aux_status_offset(void)
        return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3;
 }
 
+static int mxs_nand_gpmi_init(void)
+{
+       int ret;
+
+       /* Reset the GPMI block. */
+       ret = mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
+       if (ret)
+               return ret;
+
+       /*
+        * Choose NAND mode, set IRQ polarity, disable write protection and
+        * select BCH ECC.
+        */
+       clrsetbits_le32(&gpmi_regs->hw_gpmi_ctrl1,
+                       GPMI_CTRL1_GPMI_MODE,
+                       GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET |
+                       GPMI_CTRL1_BCH_MODE);
+       writel(0x500 << 16, &gpmi_regs->hw_gpmi_timing1);
+       return 0;
+}
+
 static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size,
                                                uint32_t page_oob_size)
 {
@@ -217,14 +346,14 @@ static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
        return block_mark_bit_offset;
 }
 
-static uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd)
+static inline uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd)
 {
        uint32_t ecc_strength;
        ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
        return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) >> 3;
 }
 
-static uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
+static inline uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
 {
        uint32_t ecc_strength;
        ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
@@ -236,12 +365,15 @@ static uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
  */
 static int mxs_nand_wait_for_bch_complete(void)
 {
-       struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
        int timeout = MXS_NAND_BCH_TIMEOUT;
        int ret;
 
        ret = mxs_wait_mask_set(&bch_regs->hw_bch_ctrl_reg,
                BCH_CTRL_COMPLETE_IRQ, timeout);
+       if (ret) {
+               debug("%s@%d: %d\n", __func__, __LINE__, ret);
+               mxs_nand_gpmi_init();
+       }
 
        writel(BCH_CTRL_COMPLETE_IRQ, &bch_regs->hw_bch_ctrl_clr);
 
@@ -325,8 +457,15 @@ static void mxs_nand_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
 
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
-       if (ret)
-               printf("MXS NAND: Error sending command\n");
+       if (ret) {
+               int i;
+
+               printf("MXS NAND: Error sending command %08lx\n", d->cmd.pio_words[0]);
+               for (i = 0; i < nand_info->cmd_queue_len; i++) {
+                       printf("%02x ", nand_info->cmd_buf[i]);
+               }
+               printf("\n");
+       }
 
        mxs_nand_return_dma_descs(nand_info);
 
@@ -341,8 +480,6 @@ static int mxs_nand_device_ready(struct mtd_info *mtd)
 {
        struct nand_chip *chip = mtd->priv;
        struct mxs_nand_info *nand_info = chip->priv;
-       struct mxs_gpmi_regs *gpmi_regs =
-               (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
        uint32_t tmp;
 
        tmp = readl(&gpmi_regs->hw_gpmi_stat);
@@ -369,6 +506,7 @@ static void mxs_nand_select_chip(struct mtd_info *mtd, int chip)
  * swapping the block mark, or swapping it *back* -- but it doesn't matter
  * because the the operation is the same.
  */
+#ifndef CONFIG_NAND_MXS_NO_BBM_SWAP
 static void mxs_nand_swap_block_mark(struct mtd_info *mtd,
                                        uint8_t *data_buf, uint8_t *oob_buf)
 {
@@ -392,6 +530,9 @@ static void mxs_nand_swap_block_mark(struct mtd_info *mtd,
 
        dst = oob_buf[0];
 
+       debug("Swapping byte %02x @ %03x.%d with %02x @ %03x\n",
+               src & 0xff, buf_offset, bit_offset, dst & 0xff, 0);
+
        oob_buf[0] = src;
 
        data_buf[buf_offset] &= ~(0xff << bit_offset);
@@ -400,6 +541,12 @@ static void mxs_nand_swap_block_mark(struct mtd_info *mtd,
        data_buf[buf_offset] |= dst << bit_offset;
        data_buf[buf_offset + 1] |= dst >> (8 - bit_offset);
 }
+#else
+static inline void mxs_nand_swap_block_mark(struct mtd_info *mtd,
+                                       uint8_t *data_buf, uint8_t *oob_buf)
+{
+}
+#endif
 
 /*
  * Read data from NAND.
@@ -422,6 +569,8 @@ static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length)
                return;
        }
 
+       memset(buf, 0xee, length);
+
        /* Compile the DMA descriptor - a descriptor that reads data. */
        d = mxs_nand_get_dma_desc(nand_info);
        d->cmd.data =
@@ -440,7 +589,7 @@ static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length)
                length;
 
        mxs_dma_desc_append(channel, d);
-
+#ifndef CONFIG_MX6Q
        /*
         * A DMA descriptor that waits for the command to end and the chip to
         * become ready.
@@ -464,11 +613,11 @@ static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length)
                GPMI_CTRL0_ADDRESS_NAND_DATA;
 
        mxs_dma_desc_append(channel, d);
-
+#endif
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret) {
-               printf("MXS NAND: DMA read error\n");
+               printf("%s: DMA read error\n", __func__);
                goto rtn;
        }
 
@@ -530,7 +679,7 @@ static void mxs_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret)
-               printf("MXS NAND: DMA write error\n");
+               printf("%s: DMA write error\n", __func__);
 
        mxs_nand_return_dma_descs(nand_info);
 }
@@ -545,6 +694,16 @@ static uint8_t mxs_nand_read_byte(struct mtd_info *mtd)
        return buf;
 }
 
+static void flush_buffers(struct mtd_info *mtd, struct mxs_nand_info *nand_info)
+{
+       flush_dcache_range((unsigned long)nand_info->data_buf,
+                       (unsigned long)nand_info->data_buf +
+                       mtd->writesize);
+       flush_dcache_range((unsigned long)nand_info->oob_buf,
+                       (unsigned long)nand_info->oob_buf +
+                       mtd->oobsize);
+}
+
 /*
  * Read a page from NAND.
  */
@@ -599,6 +758,8 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
        d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
        d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
 
+       flush_buffers(mtd, nand_info);
+
        mxs_dma_desc_append(channel, d);
 
        /* Compile the DMA descriptor - disable the BCH block. */
@@ -634,7 +795,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret) {
-               printf("MXS NAND: DMA read error\n");
+               printf("%s: DMA read error\n", __func__);
                goto rtn;
        }
 
@@ -652,7 +813,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
 
        /* Loop over status bytes, accumulating ECC status. */
        status = nand_info->oob_buf + mxs_nand_aux_status_offset();
-       for (i = 0; i < mxs_nand_ecc_chunk_cnt(mtd->writesize); i++) {
+       for (i = 0; i < mxs_nand_ecc_chunk_cnt(mtd); i++) {
                if (status[i] == 0x00)
                        continue;
 
@@ -729,10 +890,12 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
                GPMI_ECCCTRL_ENABLE_ECC |
                GPMI_ECCCTRL_ECC_CMD_ENCODE |
                GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE;
-       d->cmd.pio_words[3] = (mtd->writesize + mtd->oobsize);
+       d->cmd.pio_words[3] = mtd->writesize + mtd->oobsize;
        d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
        d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
 
+       flush_buffers(mtd, nand_info);
+
        mxs_dma_desc_append(channel, d);
 
        /* Flush caches */
@@ -741,13 +904,13 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd,
        /* Execute the DMA chain. */
        ret = mxs_dma_go(channel);
        if (ret) {
-               printf("MXS NAND: DMA write error\n");
+               printf("%s: DMA write error\n", __func__);
                goto rtn;
        }
 
        ret = mxs_nand_wait_for_bch_complete();
        if (ret) {
-               printf("MXS NAND: BCH write timeout\n");
+               printf("%s: BCH write timeout\n", __func__);
                goto rtn;
        }
 
@@ -959,7 +1122,7 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
 /*
  * Nominally, the purpose of this function is to look for or create the bad
  * block table. In fact, since the we call this function at the very end of
- * the initialization process started by nand_scan(), and we doesn't have a
+ * the initialization process started by nand_scan(), and we don't have a
  * more formal mechanism, we "hook" this function to continue init process.
  *
  * At this point, the physical NAND Flash chips have been identified and
@@ -974,14 +1137,25 @@ static int mxs_nand_scan_bbt(struct mtd_info *mtd)
 {
        struct nand_chip *nand = mtd->priv;
        struct mxs_nand_info *nand_info = nand->priv;
-       struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
        uint32_t tmp;
 
        /* Configure BCH and set NFC geometry */
-       mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
+       if (readl(&bch_regs->hw_bch_ctrl_reg) &
+               (BCH_CTRL_SFTRST | BCH_CTRL_CLKGATE))
+               /* When booting from NAND the BCH engine will already
+                * be operational and obviously does not like being reset here.
+                * There will be occasional read errors upon boot when this
+                * reset is done.
+                */
+               mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
+       readl(&bch_regs->hw_bch_ctrl_reg);
+
+       debug("mtd->writesize=%d\n", mtd->writesize);
+       debug("mtd->oobsize=%d\n", mtd->oobsize);
+       debug("ecc_strength=%d\n", mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize));
 
        /* Configure layout 0 */
-       tmp = (mxs_nand_ecc_chunk_cnt(mtd->writesize) - 1)
+       tmp = (mxs_nand_ecc_chunk_cnt(mtd) - 1)
                << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
        tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
        tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
@@ -1037,7 +1211,7 @@ int mxs_nand_alloc_buffers(struct mxs_nand_info *nand_info)
        /* DMA buffers */
        buf = memalign(MXS_DMA_ALIGNMENT, nand_info->data_buf_size);
        if (!buf) {
-               printf("MXS NAND: Error allocating DMA buffers\n");
+               printf("%s: Error allocating DMA buffers\n", __func__);
                return -ENOMEM;
        }
 
@@ -1064,56 +1238,56 @@ int mxs_nand_alloc_buffers(struct mxs_nand_info *nand_info)
  */
 int mxs_nand_init(struct mxs_nand_info *info)
 {
-       struct mxs_gpmi_regs *gpmi_regs =
-               (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
-       struct mxs_bch_regs *bch_regs =
-               (struct mxs_bch_regs *)MXS_BCH_BASE;
-       int i = 0, j;
+       int ret;
+       int i;
 
        info->desc = malloc(sizeof(struct mxs_dma_desc *) *
                                MXS_NAND_DMA_DESCRIPTOR_COUNT);
-       if (!info->desc)
+       if (!info->desc) {
+               printf("MXS NAND: Unable to allocate DMA descriptor table\n");
+               ret = -ENOMEM;
                goto err1;
+       }
+
+       mxs_dma_init();
 
        /* Allocate the DMA descriptors. */
        for (i = 0; i < MXS_NAND_DMA_DESCRIPTOR_COUNT; i++) {
                info->desc[i] = mxs_dma_desc_alloc();
-               if (!info->desc[i])
+               if (!info->desc[i]) {
+                       printf("MXS NAND: Unable to allocate DMA descriptors\n");
+                       ret = -ENOMEM;
                        goto err2;
+               }
        }
 
        /* Init the DMA controller. */
-       for (j = MXS_DMA_CHANNEL_AHB_APBH_GPMI0;
-               j <= MXS_DMA_CHANNEL_AHB_APBH_GPMI7; j++) {
-               if (mxs_dma_init_channel(j))
+       for (i = 0; i < CONFIG_SYS_NAND_MAX_CHIPS; i++) {
+               const int chan = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + i;
+
+               ret = mxs_dma_init_channel(chan);
+               if (ret) {
+                       printf("Failed to initialize DMA channel %d\n", chan);
                        goto err3;
+               }
        }
 
-       /* Reset the GPMI block. */
-       mxs_reset_block(&gpmi_regs->hw_gpmi_ctrl0_reg);
-       mxs_reset_block(&bch_regs->hw_bch_ctrl_reg);
-
-       /*
-        * Choose NAND mode, set IRQ polarity, disable write protection and
-        * select BCH ECC.
-        */
-       clrsetbits_le32(&gpmi_regs->hw_gpmi_ctrl1,
-                       GPMI_CTRL1_GPMI_MODE,
-                       GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET |
-                       GPMI_CTRL1_BCH_MODE);
+       ret = mxs_nand_gpmi_init();
+       if (ret)
+               goto err3;
 
        return 0;
 
 err3:
-       for (--j; j >= 0; j--)
-               mxs_dma_release(j);
+       for (--i; i >= 0; i--)
+               mxs_dma_release(i + MXS_DMA_CHANNEL_AHB_APBH_GPMI0);
+       i = MXS_NAND_DMA_DESCRIPTOR_COUNT - 1;
 err2:
        free(info->desc);
-err1:
        for (--i; i >= 0; i--)
                mxs_dma_desc_free(info->desc[i]);
-       printf("MXS NAND: Unable to allocate DMA descriptors\n");
-       return -ENOMEM;
+err1:
+       return ret;
 }
 
 /*!
@@ -1149,7 +1323,9 @@ int board_nand_init(struct nand_chip *nand)
 
        nand->priv = nand_info;
        nand->options |= NAND_NO_SUBPAGE_WRITE;
-
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+       nand->bbt_options |= NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
+#endif
        nand->cmd_ctrl          = mxs_nand_cmd_ctrl;
 
        nand->dev_ready         = mxs_nand_device_ready;
index 6db6566e733656d55a88c024bd1b07b5c6d58c3c..5aaea904c204bed97273f495a5ed331a77e9ebdf 100644 (file)
@@ -2508,7 +2508,7 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
        return NULL;
 }
 
-#define NOTALIGNED(x)  ((x & (chip->subpagesize - 1)) != 0)
+#define NOTALIGNED(x)  (((x) & (chip->subpagesize - 1)) != 0)
 
 /**
  * nand_do_write_ops - [INTERN] NAND write with ECC
@@ -4255,6 +4255,8 @@ int nand_scan_tail(struct mtd_info *mtd)
        ecc->steps = mtd->writesize / ecc->size;
        if (ecc->steps * ecc->size != mtd->writesize) {
                pr_warn("Invalid ECC parameters\n");
+               pr_warn("steps=%d size=%d writesize=%d\n",
+                       chip->ecc.steps, chip->ecc.size, mtd->writesize);
                BUG();
        }
        ecc->total = ecc->steps * ecc->bytes;
index 700ca324e21418bd3416599a2bc9726c007fdf03..24cbac80a25e32f27a7a297cbe95164eaf923cf8 100644 (file)
@@ -208,9 +208,16 @@ static int nand_read_page(int block, int page, void *dst)
 
 int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
 {
-       unsigned int block, lastblock;
+       unsigned int block, lastblock, bad = 0;
        unsigned int page;
+       const int ppb = CONFIG_SYS_NAND_BLOCK_SIZE / CONFIG_SYS_NAND_PAGE_SIZE;
+       int maxbad;
 
+#ifdef CONFIG_SYS_NAND_MAXBAD
+       maxbad = CONFIG_SYS_NAND_MAXBAD;
+#else
+       maxbad = mtd.size;
+#endif
        /*
         * offs has to be aligned to a page address!
         */
@@ -224,16 +231,37 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
                         * Skip bad blocks
                         */
                        while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
-                               nand_read_page(block, page, dst);
+                               if (nand_chip.ecc.read_page) {
+                                       int ret;
+
+                                       ret = nand_chip.ecc.read_page(&mtd, &nand_chip,
+                                               dst, block * ppb + page);
+                                       if (ret) {
+                                               if (page > 0)
+                                                       dst -= (page - 1) * CONFIG_SYS_NAND_PAGE_SIZE;
+                                               bad++;
+                                               lastblock++;
+                                               break;
+                                       }
+                               } else {
+                                       nand_read_page(block, page, dst);
+                               }
                                dst += CONFIG_SYS_NAND_PAGE_SIZE;
                                page++;
                        }
 
                        page = 0;
                } else {
+                       printf("Skipping bad block %d\n", block);
+                       bad++;
                        lastblock++;
                }
 
+               if (maxbad > 0 && bad > maxbad) {
+                       printf("Too many bad blocks encountered\n");
+                       return -1;
+               }
+
                block++;
        }
 
@@ -243,12 +271,21 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
 /* nand_init() - initialize data to make nand usable by SPL */
 void nand_init(void)
 {
+       static struct nand_buffers ecc_buf;
+
        /*
         * Init board specific nand support
         */
        mtd.priv = &nand_chip;
+       mtd.erasesize = CONFIG_SYS_NAND_BLOCK_SIZE;
+       mtd.writesize = CONFIG_SYS_NAND_PAGE_SIZE;
+       mtd.oobsize = CONFIG_SYS_NAND_OOBSIZE;
+
        nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W =
                (void  __iomem *)CONFIG_SYS_NAND_BASE;
+       nand_chip.oob_poi = ecc_buf.databuf;
+       nand_chip.buffers = &ecc_buf;
+
        board_nand_init(&nand_chip);
 
 #ifdef CONFIG_SPL_NAND_SOFTECC
index fc64f4814484e8052410f4769c60240ae67dc510..9c56bd3a55c09af46a61ec5c88e74acb54061b50 100644 (file)
@@ -42,6 +42,190 @@ struct omap_nand_info {
 /* We are wasting a bit of memory but al least we are safe */
 static struct omap_nand_info omap_nand_info[GPMC_MAX_CS];
 
+static struct gpmc __iomem *gpmc_cfg = (void __iomem *)GPMC_BASE;
+
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
+static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
+
+static struct nand_bbt_descr bbt_main_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+               NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+       .offs = 0, /* may be overwritten depending on ECC layout */
+       .len = 4,
+       .veroffs = 4, /* may be overwritten depending on ECC layout */
+       .maxblocks = 4,
+       .pattern = bbt_pattern,
+};
+
+static struct nand_bbt_descr bbt_mirror_descr = {
+       .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE |
+               NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
+       .offs = 0, /* may be overwritten depending on ECC layout */
+       .len = 4,
+       .veroffs = 4, /* may be overwritten depending on ECC layout */
+       .maxblocks = 4,
+       .pattern = mirror_pattern,
+};
+#endif
+
+#define PREFETCH_FIFOTHRESHOLD_MAX             0x40
+#define PREFETCH_FIFOTHRESHOLD(val)            ((val) << 8)
+
+#define PREFETCH_ENABLEOPTIMIZEDACCESS         (0x1 << 27)
+
+#define GPMC_PREFETCH_STATUS_FIFO_CNT(val)     (((val) >> 24) & 0x7F)
+#define GPMC_PREFETCH_STATUS_COUNT(val)                ((val) & 0x00003fff)
+
+#define CS_NUM_SHIFT                           24
+#define ENABLE_PREFETCH                                (0x1 << 7)
+#define DMA_MPU_MODE                           2
+
+#define OMAP_NAND_TIMEOUT_MS                   5000
+
+#define PRINT_REG(x) debug("+++ %.15s (0x%08x)=0x%08x\n", #x, &gpmc_cfg->x, readl(&gpmc_cfg->x))
+
+#ifdef CONFIG_SYS_GPMC_PREFETCH_ENABLE
+/**
+ * gpmc_prefetch_enable - configures and starts prefetch transfer
+ * @cs: cs (chip select) number
+ * @fifo_th: fifo threshold to be used for read/ write
+ * @count: number of bytes to be transferred
+ * @is_write: prefetch read(0) or write post(1) mode
+ */
+static inline void gpmc_prefetch_enable(int cs, int fifo_th,
+                                       unsigned int count, int is_write)
+{
+       writel(count, &gpmc_cfg->pref_config2);
+
+       /* Set the prefetch read / post write and enable the engine.
+        * Set which cs is has requested for.
+        */
+       uint32_t val = (cs << CS_NUM_SHIFT) |
+               PREFETCH_ENABLEOPTIMIZEDACCESS |
+               PREFETCH_FIFOTHRESHOLD(fifo_th) |
+               ENABLE_PREFETCH |
+               !!is_write;
+       writel(val, &gpmc_cfg->pref_config1);
+
+       /*  Start the prefetch engine */
+       writel(0x1, &gpmc_cfg->pref_control);
+}
+
+/**
+ * gpmc_prefetch_reset - disables and stops the prefetch engine
+ */
+static inline void gpmc_prefetch_reset(void)
+{
+       /* Stop the PFPW engine */
+       writel(0x0, &gpmc_cfg->pref_control);
+
+       /* Reset/disable the PFPW engine */
+       writel(0x0, &gpmc_cfg->pref_config1);
+}
+
+//#define FIFO_IOADDR          (nand->IO_ADDR_R)
+#define FIFO_IOADDR            PISMO1_NAND_BASE
+
+/**
+ * read_buf_pref - read data from NAND controller into buffer
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
+ */
+static void read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)
+{
+       gpmc_prefetch_enable(cs, PREFETCH_FIFOTHRESHOLD_MAX, len, 0);
+       do {
+               // Get number of bytes waiting in the FIFO
+               uint32_t read_bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(readl(&gpmc_cfg->pref_status));
+
+               if (read_bytes == 0)
+                       continue;
+               // Alignment of Destination Buffer
+               while (read_bytes && ((unsigned int)buf & 3)) {
+                       *buf++ = readb(FIFO_IOADDR);
+                       read_bytes--;
+                       len--;
+               }
+               // Use maximum word size (32bit) inside this loop, because speed is limited by
+               // GPMC bus arbitration with a maximum transfer rate of 3.000.000/sec.
+               len -= read_bytes & ~3;
+               while (read_bytes >= 4) {
+                       *((uint32_t*)buf) = readl(FIFO_IOADDR);
+                       buf += 4;
+                       read_bytes -= 4;
+               }
+               // Transfer the last (non-aligned) bytes only at the last iteration,
+               // to maintain full speed up to the end of the transfer.
+               if (read_bytes == len) {
+                       while (read_bytes) {
+                               *buf++ = readb(FIFO_IOADDR);
+                               read_bytes--;
+                       }
+                       len = 0;
+               }
+       } while (len > 0);
+       gpmc_prefetch_reset();
+}
+
+/*
+ * write_buf_pref - write buffer to NAND controller
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ */
+static void write_buf_pref(struct mtd_info *mtd, const u_char *buf, int len)
+{
+       /*  configure and start prefetch transfer */
+       gpmc_prefetch_enable(cs, PREFETCH_FIFOTHRESHOLD_MAX, len, 1);
+
+       while (len) {
+               // Get number of free bytes in the FIFO
+               uint32_t write_bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(readl(&gpmc_cfg->pref_status));
+
+               // don't write more bytes than requested
+               if (write_bytes > len)
+                       write_bytes = len;
+
+               // Alignment of Source Buffer
+               while (write_bytes && ((unsigned int)buf & 3)) {
+                       writeb(*buf++, FIFO_IOADDR);
+                       write_bytes--;
+                       len--;
+               }
+
+               // Use maximum word size (32bit) inside this loop, because speed is limited by
+               // GPMC bus arbitration with a maximum transfer rate of 3.000.000/sec.
+               len -= write_bytes & ~3;
+               while (write_bytes >= 4) {
+                       writel(*((uint32_t*)buf), FIFO_IOADDR);
+                       buf += 4;
+                       write_bytes -= 4;
+               }
+
+               // Transfer the last (non-aligned) bytes only at the last iteration,
+               // to maintain full speed up to the end of the transfer.
+               if (write_bytes == len) {
+                       while (write_bytes) {
+                               writeb(*buf++, FIFO_IOADDR);
+                               write_bytes--;
+                       }
+                       len = 0;
+               }
+       }
+
+       /* wait for data to be flushed out before resetting the prefetch */
+       while ((len = GPMC_PREFETCH_STATUS_COUNT(readl(&gpmc_cfg->pref_status)))) {
+               debug("%u bytes still in FIFO\n", PREFETCH_FIFOTHRESHOLD_MAX - len);
+               ndelay(1);
+       }
+
+       /* disable and stop the PFPW engine */
+       gpmc_prefetch_reset();
+}
+#endif /* CONFIG_SYS_GPMC_PREFETCH_ENABLE */
+
 /*
  * omap_nand_hwcontrol - Set the address pointers corretly for the
  *                     following address/data/command operation
@@ -76,7 +260,7 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
 /* Check wait pin as dev ready indicator */
 static int omap_dev_ready(struct mtd_info *mtd)
 {
-       return gpmc_cfg->status & (1 << 8);
+       return readl(&gpmc_cfg->status) & (1 << 8);
 }
 
 /*
@@ -569,14 +753,13 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
        uint8_t *ecc_calc = chip->buffers->ecccalc;
        uint8_t *ecc_code = chip->buffers->ecccode;
        uint32_t *eccpos = chip->ecc.layout->eccpos;
-       uint8_t *oob = chip->oob_poi;
+       uint8_t *oob = &chip->oob_poi[eccpos[0]];
        uint32_t data_pos;
        uint32_t oob_pos;
 
        data_pos = 0;
        /* oob area start */
-       oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
-       oob += chip->ecc.layout->eccpos[0];
+       oob_pos = (eccsize * eccsteps) + eccpos[0];
 
        for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
                                oob += eccbytes) {
@@ -591,6 +774,12 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
                /* read syndrome */
                chip->ecc.calculate(mtd, p, &ecc_calc[i]);
 
+               if (oob_required) {
+                       /* reread the OOB area to get the metadata */
+                       chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, page);
+                       chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
+               }
+
                data_pos += eccsize;
                oob_pos += eccbytes;
        }
@@ -644,22 +833,22 @@ static int omap_correct_data_bch_sw(struct mtd_info *mtd, u_char *data,
                                data[errloc[i]/8] ^= 1 << (errloc[i] & 7);
                        printf("corrected bitflip %u\n", errloc[i]);
 #ifdef DEBUG
-                       puts("read_ecc: ");
+                       printf("read_ecc: ");
                        /*
                         * BCH8 have 13 bytes of ECC; BCH4 needs adoption
                         * here!
                         */
                        for (i = 0; i < 13; i++)
                                printf("%02x ", read_ecc[i]);
-                       puts("\n");
-                       puts("calc_ecc: ");
+                       printf("\n");
+                       printf("calc_ecc: ");
                        for (i = 0; i < 13; i++)
                                printf("%02x ", calc_ecc[i]);
-                       puts("\n");
+                       printf("\n");
 #endif
                }
        } else if (count < 0) {
-               puts("ecc unrecoverable error\n");
+               printf("ecc unrecoverable error\n");
        }
        return count;
 }
@@ -988,6 +1177,21 @@ int board_nand_init(struct nand_chip *nand)
 #endif
        if (err)
                return err;
+#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
+       if (nand->ecc.layout) {
+               bbt_main_descr.offs = nand->ecc.layout->oobfree[0].offset;
+               bbt_main_descr.veroffs = bbt_main_descr.offs +
+                       sizeof(bbt_pattern);
+
+               bbt_mirror_descr.offs = nand->ecc.layout->oobfree[0].offset;
+               bbt_mirror_descr.veroffs = bbt_mirror_descr.offs +
+                       sizeof(mirror_pattern);
+       }
+
+       nand->bbt_options |= NAND_BBT_USE_FLASH;
+       nand->bbt_td = &bbt_main_descr;
+       nand->bbt_md = &bbt_mirror_descr;
+#endif
 
 #ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH
        /* TODO: Implement for 16-bit bus width */
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c5736b0c3775e79ee5cafe8e1f083458883622ee 100644 (file)
@@ -0,0 +1,33 @@
+menuconfig NETDEVICES
+       bool "Network device support"
+       depends on NET
+
+if NETDEVICES
+
+config MII
+       bool
+
+config FEC_MXC
+       bool "Freescale FEC ethernet controller"
+       select MII
+
+config GET_FEC_MAC_ADDR_FROM_IIM
+       bool "Read FEC MAC address from fuses"
+       depends on FEC_MXC
+
+if FEC_MXC
+
+config FEC_MXC_MULTI
+       bool "Support multiple ethernet interfaces"
+       depends on MX28 || MX6
+
+config FEC_MXC_PHYADDR
+       int "FEC Ethernet PHY address"
+               default 0
+       depends on !FEC_MXC_MULTI
+
+endif
+
+source "drivers/net/phy/Kconfig"
+
+endif
index 52f8da67e1d9049da108238e8955ae2de3d0fce5..725108d0ea392f15f7e09c178093a9eb6eb9db91 100644 (file)
 #include <malloc.h>
 #include <net.h>
 #include <netdev.h>
-#include <cpsw.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <phy.h>
 #include <asm/arch/cpu.h>
 
 #define BITMASK(bits)          (BIT(bits) - 1)
+
 #define PHY_REG_MASK           0x1f
 #define PHY_ID_MASK            0x1f
 #define NUM_DESCS              (PKTBUFSRX * 2)
 #define PKT_MIN                        60
 #define PKT_MAX                        (1500 + 14 + 4 + 4)
 #define CLEAR_BIT              1
+
+/* MAC_CONTROL register bits */
 #define GIGABITEN              BIT(7)
 #define FULLDUPLEXEN           BIT(0)
+#define MAC_CTRL_CMD_IDLE      BIT(11)
 #define MIIEN                  BIT(15)
 
+/* MAC_STATUS register bits */
+#define MAC_STAT_IDLE          BIT(31)
+
 /* DMA Registers */
 #define CPDMA_TXCONTROL                0x004
 #define CPDMA_RXCONTROL                0x014
 #define CPDMA_SOFTRESET                0x01c
+#define CPDMA_DMACONTROL       0x020
+#define CPDMA_DMASTATUS                0x024
 #define CPDMA_RXFREE           0x0e0
 #define CPDMA_TXHDP_VER1       0x100
 #define CPDMA_TXHDP_VER2       0x200
 #define CPDMA_RXCP_VER1                0x160
 #define CPDMA_RXCP_VER2                0x260
 
+#define DMACONTROL_CMD_IDLE    BIT(3)
+
+#define DMASTATUS_IDLE         BIT(31)
+
 /* Descriptor mode bits */
 #define CPDMA_DESC_SOP         BIT(31)
 #define CPDMA_DESC_EOP         BIT(30)
@@ -88,8 +100,8 @@ struct cpsw_mdio_regs {
 #define USERACCESS_GO          BIT(31)
 #define USERACCESS_WRITE       BIT(30)
 #define USERACCESS_ACK         BIT(29)
-#define USERACCESS_READ                (0)
-#define USERACCESS_DATA                (0xffff)
+#define USERACCESS_READ                0
+#define USERACCESS_DATA                0xffff
        } user[0];
 };
 
@@ -193,19 +205,22 @@ struct cpdma_desc {
        u32                     hw_buffer;
        u32                     hw_len;
        u32                     hw_mode;
-       /* software fields */
-       u32                     sw_buffer;
-       u32                     sw_len;
+} __attribute__((aligned(CONFIG_SYS_CACHELINE_SIZE)));
+
+struct cpsw_desc {
+       void *sw_buffer;
+       struct cpsw_desc *next;
+       struct cpdma_desc *dma_desc;
 };
 
 struct cpdma_chan {
-       struct cpdma_desc       *head, *tail;
+       struct cpsw_desc        *head, *tail;
        void                    *hdp, *cp, *rxfree;
 };
 
-#define desc_write(desc, fld, val)     __raw_writel((u32)(val), &(desc)->fld)
-#define desc_read(desc, fld)           __raw_readl(&(desc)->fld)
-#define desc_read_ptr(desc, fld)       ((void *)__raw_readl(&(desc)->fld))
+#define desc_write(desc, fld, val)     __raw_writel((u32)(val), &(desc)->dma_desc->fld)
+#define desc_read(desc, fld)           __raw_readl(&(desc)->dma_desc->fld)
+#define desc_read_ptr(desc, fld)       ((void *)__raw_readl(&(desc)->dma_desc->fld))
 
 #define chan_write(chan, fld, val)     __raw_writel((u32)(val), (chan)->fld)
 #define chan_read(chan, fld)           __raw_readl((chan)->fld)
@@ -215,11 +230,11 @@ struct cpdma_chan {
        slave = (priv)->slaves + (priv)->data.active_slave; if (slave)
 #define for_each_slave(slave, priv) \
        for (slave = (priv)->slaves; slave != (priv)->slaves + \
-                               (priv)->data.slaves; slave++)
+                               (priv)->data->slaves; slave++)
 
 struct cpsw_priv {
        struct eth_device               *dev;
-       struct cpsw_platform_data       data;
+       struct cpsw_platform_data       *data;
        int                             host_port;
 
        struct cpsw_regs                *regs;
@@ -227,8 +242,8 @@ struct cpsw_priv {
        struct cpsw_host_regs           *host_port_regs;
        void                            *ale_regs;
 
-       struct cpdma_desc               *descs;
-       struct cpdma_desc               *desc_free;
+       struct cpsw_desc                descs[NUM_DESCS];
+       struct cpsw_desc                *desc_free;
        struct cpdma_chan               rx_chan, tx_chan;
 
        struct cpsw_slave               *slaves;
@@ -326,7 +341,7 @@ static int cpsw_ale_match_addr(struct cpsw_priv *priv, u8* addr)
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
 
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                u8 entry_addr[6];
 
                cpsw_ale_read(priv, idx, ale_entry);
@@ -345,7 +360,7 @@ static int cpsw_ale_match_free(struct cpsw_priv *priv)
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
 
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                cpsw_ale_read(priv, idx, ale_entry);
                type = cpsw_ale_get_entry_type(ale_entry);
                if (type == ALE_TYPE_FREE)
@@ -359,7 +374,7 @@ static int cpsw_ale_find_ageable(struct cpsw_priv *priv)
        u32 ale_entry[ALE_ENTRY_WORDS];
        int type, idx;
 
-       for (idx = 0; idx < priv->data.ale_entries; idx++) {
+       for (idx = 0; idx < priv->data->ale_entries; idx++) {
                cpsw_ale_read(priv, idx, ale_entry);
                type = cpsw_ale_get_entry_type(ale_entry);
                if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
@@ -458,17 +473,17 @@ static struct cpsw_mdio_regs *mdio_regs;
 /* wait until hardware is ready for another user access */
 static inline u32 wait_for_user_access(void)
 {
-       u32 reg = 0;
        int timeout = MDIO_TIMEOUT;
+       u32 reg;
 
-       while (timeout-- &&
-       ((reg = __raw_readl(&mdio_regs->user[0].access)) & USERACCESS_GO))
-               udelay(10);
-
-       if (timeout == -1) {
-               printf("wait_for_user_access Timeout\n");
-               return -ETIMEDOUT;
+       while ((reg = __raw_readl(&mdio_regs->user[0].access)) & USERACCESS_GO) {
+               udelay(1000);
+               if (--timeout <= 0) {
+                       printf("TIMEOUT waiting for USERACCESS_GO\n");
+                       break;
+               }
        }
+
        return reg;
 }
 
@@ -477,12 +492,13 @@ static inline void wait_for_idle(void)
 {
        int timeout = MDIO_TIMEOUT;
 
-       while (timeout-- &&
-               ((__raw_readl(&mdio_regs->control) & CONTROL_IDLE) == 0))
-               udelay(10);
-
-       if (timeout == -1)
-               printf("wait_for_idle Timeout\n");
+       while ((__raw_readl(&mdio_regs->control) & CONTROL_IDLE) == 0) {
+               if (--timeout <= 0) {
+                       printf("TIMEOUT waiting for state machine idle\n");
+                       break;
+               }
+               udelay(1000);
+       }
 }
 
 static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
@@ -494,11 +510,16 @@ static int cpsw_mdio_read(struct mii_dev *bus, int phy_id,
        if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
                return -EINVAL;
 
-       wait_for_user_access();
+       if (wait_for_user_access() & USERACCESS_GO)
+               /* promote error from previous access */
+               return -ETIME;
+
        reg = (USERACCESS_GO | USERACCESS_READ | (phy_reg << 21) |
               (phy_id << 16));
        __raw_writel(reg, &mdio_regs->user[0].access);
        reg = wait_for_user_access();
+       if (reg & USERACCESS_GO)
+               return -ETIME;
 
        data = (reg & USERACCESS_ACK) ? (reg & USERACCESS_DATA) : -1;
        return data;
@@ -512,11 +533,15 @@ static int cpsw_mdio_write(struct mii_dev *bus, int phy_id, int dev_addr,
        if (phy_reg & ~PHY_REG_MASK || phy_id & ~PHY_ID_MASK)
                return -EINVAL;
 
-       wait_for_user_access();
+       if (wait_for_user_access() & USERACCESS_GO)
+               /* promote error from previous access */
+               return -ETIME;
+
        reg = (USERACCESS_GO | USERACCESS_WRITE | (phy_reg << 21) |
                   (phy_id << 16) | (data & USERACCESS_DATA));
        __raw_writel(reg, &mdio_regs->user[0].access);
-       wait_for_user_access();
+       if (wait_for_user_access() & USERACCESS_GO)
+               return -ETIME;
 
        return 0;
 }
@@ -550,9 +575,12 @@ static void cpsw_mdio_init(char *name, u32 mdio_base, u32 div)
 /* Set a self-clearing bit in a register, and wait for it to clear */
 static inline void setbit_and_wait_for_clear32(void *addr)
 {
+       int loops = 0;
+
        __raw_writel(CLEAR_BIT, addr);
        while (__raw_readl(addr) & CLEAR_BIT)
-               ;
+               loops++;
+       debug("%s: reset finished after %u loops\n", __func__, loops);
 }
 
 #define mac_hi(mac)    (((mac)[0] << 0) | ((mac)[1] << 8) |    \
@@ -566,29 +594,32 @@ static void cpsw_set_slave_mac(struct cpsw_slave *slave,
        __raw_writel(mac_lo(priv->dev->enetaddr), &slave->regs->sa_lo);
 }
 
+#define NUM_TRIES 50
 static void cpsw_slave_update_link(struct cpsw_slave *slave,
                                   struct cpsw_priv *priv, int *link)
 {
        struct phy_device *phy;
        u32 mac_control = 0;
-
-       phy = priv->phydev;
-
-       if (!phy)
-               return;
-
-       phy_startup(phy);
-       *link = phy->link;
-
-       if (*link) { /* link up */
-               mac_control = priv->data.mac_control;
-               if (phy->speed == 1000)
-                       mac_control |= GIGABITEN;
-               if (phy->duplex == DUPLEX_FULL)
-                       mac_control |= FULLDUPLEXEN;
-               if (phy->speed == 100)
-                       mac_control |= MIIEN;
-       }
+       int retries = NUM_TRIES;
+
+       do {
+               phy_startup(phy);
+               *link = phy->link;
+
+               if (*link) { /* link up */
+                       mac_control = priv->data->mac_control;
+                       if (phy->speed == 1000)
+                               mac_control |= GIGABITEN;
+                       if (phy->duplex == DUPLEX_FULL)
+                               mac_control |= FULLDUPLEXEN;
+                       if (phy->speed == 100)
+                               mac_control |= MIIEN;
+               } else {
+                       udelay(10000);
+               }
+       } while (!*link && retries-- > 0);
+       debug("%s: mac_control: %08x -> %08x after %u loops\n", __func__,
+               slave->mac_control, mac_control, NUM_TRIES - retries);
 
        if (mac_control == slave->mac_control)
                return;
@@ -628,6 +659,7 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
 {
        u32     slave_port;
 
+       debug("%s\n", __func__);
        setbit_and_wait_for_clear32(&slave->sliver->soft_reset);
 
        /* setup priority mapping */
@@ -649,19 +681,33 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
        priv->phy_mask |= 1 << slave->data->phy_addr;
 }
 
-static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv)
+static void cpdma_desc_get(struct cpsw_desc *desc)
+{
+       invalidate_dcache_range((u32)desc->dma_desc, (u32)(&desc->dma_desc[1]));
+}
+
+static void cpdma_desc_put(struct cpsw_desc *desc)
+{
+       flush_dcache_range((u32)desc->dma_desc, (u32)(&desc->dma_desc[1]));
+}
+
+static struct cpsw_desc *cpdma_desc_alloc(struct cpsw_priv *priv)
 {
-       struct cpdma_desc *desc = priv->desc_free;
+       struct cpsw_desc *desc = priv->desc_free;
 
-       if (desc)
-               priv->desc_free = desc_read_ptr(desc, hw_next);
+       if (desc) {
+               cpdma_desc_get(desc);
+               priv->desc_free = desc->next;
+       }
        return desc;
 }
 
-static void cpdma_desc_free(struct cpsw_priv *priv, struct cpdma_desc *desc)
+static void cpdma_desc_free(struct cpsw_priv *priv, struct cpsw_desc *desc)
 {
        if (desc) {
-               desc_write(desc, hw_next, priv->desc_free);
+               desc_write(desc, hw_next, priv->desc_free->dma_desc);
+               cpdma_desc_put(desc);
+               desc->next = priv->desc_free;
                priv->desc_free = desc;
        }
 }
@@ -669,76 +715,89 @@ static void cpdma_desc_free(struct cpsw_priv *priv, struct cpdma_desc *desc)
 static int cpdma_submit(struct cpsw_priv *priv, struct cpdma_chan *chan,
                        void *buffer, int len)
 {
-       struct cpdma_desc *desc, *prev;
+       struct cpsw_desc *desc, *prev;
        u32 mode;
 
+       if (!buffer) {
+               printf("ERROR: %s() NULL buffer\n", __func__);
+               return -EINVAL;
+       }
+
+       flush_dcache_range((u32)buffer, (u32)buffer + len);
+
        desc = cpdma_desc_alloc(priv);
        if (!desc)
                return -ENOMEM;
 
+       debug("%s@%d: %cX desc %p DMA %p\n", __func__, __LINE__,
+               chan == &priv->rx_chan ? 'R' : 'T', desc, desc->dma_desc);
        if (len < PKT_MIN)
                len = PKT_MIN;
 
        mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
 
+       desc->next = NULL;
        desc_write(desc, hw_next,   0);
        desc_write(desc, hw_buffer, buffer);
        desc_write(desc, hw_len,    len);
        desc_write(desc, hw_mode,   mode | len);
-       desc_write(desc, sw_buffer, buffer);
-       desc_write(desc, sw_len,    len);
 
+       desc->sw_buffer = buffer;
+
+       cpdma_desc_put(desc);
        if (!chan->head) {
                /* simple case - first packet enqueued */
                chan->head = desc;
                chan->tail = desc;
-               chan_write(chan, hdp, desc);
+               chan_write(chan, hdp, desc->dma_desc);
                goto done;
        }
 
        /* not the first packet - enqueue at the tail */
        prev = chan->tail;
-       desc_write(prev, hw_next, desc);
+
+       prev->next = desc;
+       cpdma_desc_get(prev);
+       desc_write(prev, hw_next, desc->dma_desc);
+       cpdma_desc_put(prev);
+
        chan->tail = desc;
 
        /* next check if EOQ has been triggered already */
        if (desc_read(prev, hw_mode) & CPDMA_DESC_EOQ)
-               chan_write(chan, hdp, desc);
+               chan_write(chan, hdp, desc->dma_desc);
 
 done:
        if (chan->rxfree)
                chan_write(chan, rxfree, 1);
+       debug("%s@%d\n", __func__, __LINE__);
        return 0;
 }
 
 static int cpdma_process(struct cpsw_priv *priv, struct cpdma_chan *chan,
                         void **buffer, int *len)
 {
-       struct cpdma_desc *desc = chan->head;
+       struct cpsw_desc *desc = chan->head;
        u32 status;
 
        if (!desc)
                return -ENOENT;
 
+       cpdma_desc_get(desc);
+
        status = desc_read(desc, hw_mode);
+       if (status & CPDMA_DESC_OWNER)
+               return -EBUSY;
 
        if (len)
                *len = status & 0x7ff;
 
        if (buffer)
-               *buffer = desc_read_ptr(desc, sw_buffer);
-
-       if (status & CPDMA_DESC_OWNER) {
-               if (chan_read(chan, hdp) == 0) {
-                       if (desc_read(desc, hw_mode) & CPDMA_DESC_OWNER)
-                               chan_write(chan, hdp, desc);
-               }
-
-               return -EBUSY;
-       }
+               *buffer = desc->sw_buffer;
+       debug("%s@%d: buffer=%p\n", __func__, __LINE__, desc->sw_buffer);
 
-       chan->head = desc_read_ptr(desc, hw_next);
-       chan_write(chan, cp, desc);
+       chan->head = desc->next;
+       chan_write(chan, cp, desc->dma_desc);
 
        cpdma_desc_free(priv, desc);
        return 0;
@@ -750,6 +809,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
        struct cpsw_slave       *slave;
        int i, ret;
 
+       debug("%s\n", __func__);
        /* soft reset the controller and initialize priv */
        setbit_and_wait_for_clear32(&priv->regs->soft_reset);
 
@@ -782,60 +842,55 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
 
        /* init descriptor pool */
        for (i = 0; i < NUM_DESCS; i++) {
+               struct cpsw_desc *next_desc = (i < (NUM_DESCS - 1)) ?
+                       &priv->descs[i + 1] : NULL;
+
+               priv->descs[i].next = next_desc;
                desc_write(&priv->descs[i], hw_next,
-                          (i == (NUM_DESCS - 1)) ? 0 : &priv->descs[i+1]);
+                       next_desc ? next_desc->dma_desc : 0);
+               cpdma_desc_put(&priv->descs[i]);
        }
        priv->desc_free = &priv->descs[0];
 
        /* initialize channels */
-       if (priv->data.version == CPSW_CTRL_VERSION_2) {
+       if (priv->data->version == CPSW_CTRL_VERSION_2) {
                memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
-               priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER2;
-               priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER2;
-               priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
+               priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER2;
+               priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER2;
+               priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
 
                memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
-               priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER2;
-               priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER2;
+               priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER2;
+               priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER2;
        } else {
                memset(&priv->rx_chan, 0, sizeof(struct cpdma_chan));
-               priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER1;
-               priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER1;
-               priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
+               priv->rx_chan.hdp       = priv->dma_regs + CPDMA_RXHDP_VER1;
+               priv->rx_chan.cp        = priv->dma_regs + CPDMA_RXCP_VER1;
+               priv->rx_chan.rxfree    = priv->dma_regs + CPDMA_RXFREE;
 
                memset(&priv->tx_chan, 0, sizeof(struct cpdma_chan));
-               priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER1;
-               priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER1;
+               priv->tx_chan.hdp       = priv->dma_regs + CPDMA_TXHDP_VER1;
+               priv->tx_chan.cp        = priv->dma_regs + CPDMA_TXCP_VER1;
        }
 
        /* clear dma state */
        setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET);
 
-       if (priv->data.version == CPSW_CTRL_VERSION_2) {
-               for (i = 0; i < priv->data.channels; i++) {
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER2 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER2 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER2 + 4
-                                       * i);
+       if (priv->data->version == CPSW_CTRL_VERSION_2) {
+               for (i = 0; i < priv->data->channels; i++) {
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER2 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER2 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER2 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER2 + 4 * i);
                }
        } else {
-               for (i = 0; i < priv->data.channels; i++) {
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER1 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER1 + 4
-                                       * i);
-                       __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER1 + 4
-                                       * i);
+               for (i = 0; i < priv->data->channels; i++) {
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXHDP_VER1 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXFREE + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_RXCP_VER1 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_TXHDP_VER1 + 4 * i);
+                       __raw_writel(0, priv->dma_regs + CPDMA_TXCP_VER1 + 4 * i);
 
                }
        }
@@ -853,12 +908,37 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
                }
        }
 
-       return 0;
+       return ret;
 }
 
 static void cpsw_halt(struct eth_device *dev)
 {
        struct cpsw_priv        *priv = dev->priv;
+       struct cpsw_slave       *slave;
+       int idle = 0;
+       int timeout = 1000000;
+
+       __raw_writel(DMACONTROL_CMD_IDLE, priv->dma_regs + CPDMA_DMACONTROL);
+       while (!(__raw_readl(priv->dma_regs + CPDMA_DMASTATUS) &
+                       DMASTATUS_IDLE) && (--timeout >= 0))
+               udelay(1);
+
+       timeout = 1000000;
+       while (!idle) {
+               idle = 1;
+               for_each_slave(slave, priv) {
+                       if (!(__raw_readl(&slave->sliver->mac_status) &
+                                       MAC_STAT_IDLE)) {
+                               idle = 0;
+                               break;
+                       }
+               }
+               if (idle || --timeout < 0)
+                       break;
+               udelay(1);
+       }
+       if (!idle)
+               printf("CPSW: Aborting DMA transfers; packets may be lost\n");
 
        writel(0, priv->dma_regs + CPDMA_TXCONTROL);
        writel(0, priv->dma_regs + CPDMA_RXCONTROL);
@@ -869,28 +949,20 @@ static void cpsw_halt(struct eth_device *dev)
        /* clear dma state */
        setbit_and_wait_for_clear32(priv->dma_regs + CPDMA_SOFTRESET);
 
-       priv->data.control(0);
+       debug("%s\n", __func__);
+       priv->data->control(0);
 }
 
 static int cpsw_send(struct eth_device *dev, void *packet, int length)
 {
-       struct cpsw_priv        *priv = dev->priv;
+       struct cpsw_priv *priv = dev->priv;
        void *buffer;
        int len;
-       int timeout = CPDMA_TIMEOUT;
 
-       flush_dcache_range((unsigned long)packet,
-                          (unsigned long)packet + length);
 
        /* first reap completed packets */
-       while (timeout-- &&
-               (cpdma_process(priv, &priv->tx_chan, &buffer, &len) >= 0))
-               ;
-
-       if (timeout == -1) {
-               printf("cpdma_process timeout\n");
-               return -ETIMEDOUT;
-       }
+       while (cpdma_process(priv, &priv->tx_chan, &buffer, &len) == 0)
+               /* NOP */;
 
        return cpdma_submit(priv, &priv->tx_chan, packet, length);
 }
@@ -901,11 +973,14 @@ static int cpsw_recv(struct eth_device *dev)
        void *buffer;
        int len;
 
-       while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
-               invalidate_dcache_range((unsigned long)buffer,
-                                       (unsigned long)buffer + PKTSIZE_ALIGN);
-               NetReceive(buffer, len);
-               cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
+       while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) == 0) {
+               if (buffer) {
+                       NetReceive(buffer, len);
+                       cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
+               } else {
+                       printf("NULL buffer returned from cpdma_process\n");
+                       return -EIO;
+               }
        }
 
        return 0;
@@ -915,7 +990,10 @@ static void cpsw_slave_setup(struct cpsw_slave *slave, int slave_num,
                            struct cpsw_priv *priv)
 {
        void                    *regs = priv->regs;
-       struct cpsw_slave_data  *data = priv->data.slave_data + slave_num;
+       struct cpsw_slave_data  *data = priv->data->slave_data + slave_num;
+
+       debug("%s@%d: slave[%d] %p\n", __func__, __LINE__,
+               slave_num, slave);
        slave->slave_num = slave_num;
        slave->data     = data;
        slave->regs     = regs + data->slave_reg_ofs;
@@ -928,10 +1006,27 @@ static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave)
        struct phy_device *phydev;
        u32 supported = PHY_GBIT_FEATURES;
 
-       phydev = phy_connect(priv->bus,
-                       slave->data->phy_addr,
-                       dev,
-                       slave->data->phy_if);
+       if (slave->data->phy_id < 0) {
+               u32 phy_addr;
+
+               for (phy_addr = 0; phy_addr < 32; phy_addr++) {
+                       debug("Trying to connect to PHY @ addr %02x\n",
+                               phy_addr);
+                       phydev = phy_connect(priv->bus, phy_addr,
+                                       dev, slave->data->phy_if);
+                       if (phydev)
+                               break;
+               }
+       } else {
+               phydev = phy_connect(priv->bus,
+                               slave->data->phy_id,
+                               dev,
+                               slave->data->phy_if);
+       }
+       if (!phydev) {
+               printf("Failed to connect to PHY\n");
+               return -EINVAL;
+       }
 
        if (!phydev)
                return -1;
@@ -942,15 +1037,20 @@ static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave)
        priv->phydev = phydev;
        phy_config(phydev);
 
-       return 1;
+       return 0;
 }
 
 int cpsw_register(struct cpsw_platform_data *data)
 {
+       int ret = 1;
        struct cpsw_priv        *priv;
        struct cpsw_slave       *slave;
        void                    *regs = (void *)data->cpsw_base;
        struct eth_device       *dev;
+       int i;
+       int idx = 0;
+
+       debug("%s@%d\n", __func__, __LINE__);
 
        dev = calloc(sizeof(*dev), 1);
        if (!dev)
@@ -962,10 +1062,10 @@ int cpsw_register(struct cpsw_platform_data *data)
                return -ENOMEM;
        }
 
-       priv->data = *data;
+       priv->data = data;
        priv->dev = dev;
 
-       priv->slaves = malloc(sizeof(struct cpsw_slave) * data->slaves);
+       priv->slaves = calloc(sizeof(struct cpsw_slave), data->slaves);
        if (!priv->slaves) {
                free(dev);
                free(priv);
@@ -979,8 +1079,6 @@ int cpsw_register(struct cpsw_platform_data *data)
        priv->ale_regs          = regs + data->ale_reg_ofs;
        priv->descs             = (void *)regs + data->bd_ram_ofs;
 
-       int idx = 0;
-
        for_each_slave(slave, priv) {
                cpsw_slave_setup(slave, idx, priv);
                idx = idx + 1;
@@ -998,8 +1096,10 @@ int cpsw_register(struct cpsw_platform_data *data)
 
        cpsw_mdio_init(dev->name, data->mdio_base, data->mdio_div);
        priv->bus = miiphy_get_dev_by_name(dev->name);
-       for_active_slave(slave, priv)
-               cpsw_phy_init(dev, slave);
-
-       return 1;
+       for_active_slave(slave, priv) {
+               ret = cpsw_phy_init(dev, slave);
+               if (ret < 0)
+                       break;
+       }
+       return ret;
 }
index b57247032fa85aaa65ec47c9fcf7668a4cd567df..63f03e6202fed61f3229837541eb505104888d9a 100644 (file)
 #include <net.h>
 #include <netdev.h>
 #include <miiphy.h>
-#include "fec_mxc.h"
 
+#include <asm/arch/sys_proto.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <linux/compiler.h>
 
+#include "fec_mxc.h"
+
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -74,6 +76,8 @@ struct nbuf {
        uint8_t head[16];       /**< MAC header(6 + 6 + 2) + 2(aligned) */
 };
 
+static int rx_idx;
+
 #ifdef CONFIG_FEC_MXC_SWAP_PACKET
 static void swap_packet(uint32_t *packet, int length)
 {
@@ -92,7 +96,7 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
 {
        uint32_t reg;           /* convenient holder for the PHY register */
        uint32_t phy;           /* convenient holder for the PHY */
-       uint32_t start;
+       ulong start;
        int val;
 
        /*
@@ -112,6 +116,8 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
        start = get_timer(0);
        while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
                if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
+                       if (readl(&eth->ievent) & FEC_IEVENT_MII)
+                               break;
                        printf("Read MDIO failed...\n");
                        return -1;
                }
@@ -126,7 +132,7 @@ static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
         * it's now safe to read the PHY's register
         */
        val = (unsigned short)readl(&eth->mii_data);
-       debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
+       debug("%s: phy: %02x reg:%02x val:%#06x\n", __func__, phyAddr,
                        regAddr, val);
        return val;
 }
@@ -151,7 +157,7 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
 {
        uint32_t reg;           /* convenient holder for the PHY register */
        uint32_t phy;           /* convenient holder for the PHY */
-       uint32_t start;
+       ulong start;
 
        reg = regAddr << FEC_MII_DATA_RA_SHIFT;
        phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
@@ -165,6 +171,8 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
        start = get_timer(0);
        while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
                if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
+                       if (readl(&eth->ievent) & FEC_IEVENT_MII)
+                               break;
                        printf("Write MDIO failed...\n");
                        return -1;
                }
@@ -174,7 +182,7 @@ static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
         * clear MII interrupt bit
         */
        writel(FEC_IEVENT_MII, &eth->ievent);
-       debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyAddr,
+       debug("%s: phy: %02x reg:%02x val:%#06x\n", __func__, phyAddr,
                        regAddr, data);
 
        return 0;
@@ -255,26 +263,22 @@ static int miiphy_wait_aneg(struct eth_device *dev)
 }
 #endif
 
-static int fec_rx_task_enable(struct fec_priv *fec)
+static inline void fec_rx_task_enable(struct fec_priv *fec)
 {
-       writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active);
-       return 0;
+       writel(1 << 24, &fec->eth->r_des_active);
 }
 
-static int fec_rx_task_disable(struct fec_priv *fec)
+static inline void fec_rx_task_disable(struct fec_priv *fec)
 {
-       return 0;
 }
 
-static int fec_tx_task_enable(struct fec_priv *fec)
+static inline void fec_tx_task_enable(struct fec_priv *fec)
 {
-       writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active);
-       return 0;
+       writel(1 << 24, &fec->eth->x_des_active);
 }
 
-static int fec_tx_task_disable(struct fec_priv *fec)
+static inline void fec_tx_task_disable(struct fec_priv *fec)
 {
-       return 0;
 }
 
 /**
@@ -420,7 +424,7 @@ static void fec_reg_setup(struct fec_priv *fec)
  */
 static int fec_open(struct eth_device *edev)
 {
-       struct fec_priv *fec = (struct fec_priv *)edev->priv;
+       struct fec_priv *fec = edev->priv;
        int speed;
        uint32_t addr, size;
        int i;
@@ -505,6 +509,7 @@ static int fec_open(struct eth_device *edev)
        {
                u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED;
                u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T;
+
                if (speed == _1000BASET)
                        ecr |= FEC_ECNTRL_SPEED;
                else if (speed != _100BASET)
@@ -512,6 +517,14 @@ static int fec_open(struct eth_device *edev)
                writel(ecr, &fec->eth->ecntrl);
                writel(rcr, &fec->eth->r_cntrl);
        }
+#elif defined(CONFIG_MX28)
+       {
+               u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T;
+
+               if (speed == _10BASET)
+                       rcr |= FEC_RCNTRL_RMII_10T;
+               writel(rcr, &fec->eth->r_cntrl);
+       }
 #endif
        debug("%s:Speed=%i\n", __func__, speed);
 
@@ -520,14 +533,14 @@ static int fec_open(struct eth_device *edev)
         */
        fec_rx_task_enable(fec);
 
-       udelay(100000);
+//     udelay(100000);
        return 0;
 }
 
 static int fec_init(struct eth_device *dev, bd_t* bd)
 {
-       struct fec_priv *fec = (struct fec_priv *)dev->priv;
-       uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
+       struct fec_priv *fec = dev->priv;
+       uint32_t *mib_ptr = (uint32_t *)&fec->eth->rmon_t_drop;
        int i;
 
        /* Initialize MAC address */
@@ -559,8 +572,8 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 
 
        /* clear MIB RAM */
-       for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4)
-               writel(0, i);
+       for (i = 0; i <= 0xfc >> 2; i++)
+               writel(0, &mib_ptr[i]);
 
        /* FIFO receive start register */
        writel(0x520, &fec->eth->r_fstart);
@@ -585,7 +598,7 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
 static void fec_halt(struct eth_device *dev)
 {
        struct fec_priv *fec = (struct fec_priv *)dev->priv;
-       int counter = 0xffff;
+       int counter = 1000;
 
        /*
         * issue graceful stop command to the FEC transmitter if necessary
@@ -598,7 +611,7 @@ static void fec_halt(struct eth_device *dev)
         * wait for graceful stop to register
         */
        while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA)))
-               udelay(1);
+               udelay(100);
 
        /*
         * Disable SmartDMA tasks
@@ -636,7 +649,7 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
         * This routine transmits one frame.  This routine only accepts
         * 6-byte Ethernet addresses.
         */
-       struct fec_priv *fec = (struct fec_priv *)dev->priv;
+       struct fec_priv *fec = dev->priv;
 
        /*
         * Check for valid length of data.
@@ -661,13 +674,14 @@ static int fec_send(struct eth_device *dev, void *packet, int length)
        flush_dcache_range(addr, end);
 
        writew(length, &fec->tbd_base[fec->tbd_index].data_length);
-       writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer);
+       writel((unsigned long)packet,
+               &fec->tbd_base[fec->tbd_index].data_pointer);
 
        /*
         * update BD's status now
         * This block:
         * - is always the last in a chain (means no chain)
-        * - should transmitt the CRC
+        * - should transmit the CRC
         * - might be the last BD in the list, so the address counter should
         *   wrap (-> keep the WRAP flag)
         */
@@ -779,14 +793,16 @@ static int fec_recv(struct eth_device *dev)
        uint16_t bd_status;
        uint32_t addr, size, end;
        int i;
-       ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE);
 
        /*
         * Check if any critical events have happened
         */
        ievent = readl(&fec->eth->ievent);
-       writel(ievent, &fec->eth->ievent);
-       debug("fec_recv: ievent 0x%lx\n", ievent);
+       if (ievent)
+               writel(ievent, &fec->eth->ievent);
+
+       if (ievent)
+               debug("fec_recv: ievent 0x%lx\n", ievent);
        if (ievent & FEC_IEVENT_BABR) {
                fec_halt(dev);
                fec_init(dev, fec->bd);
@@ -827,9 +843,9 @@ static int fec_recv(struct eth_device *dev)
        invalidate_dcache_range(addr, addr + size);
 
        bd_status = readw(&rbd->status);
-       debug("fec_recv: status 0x%x\n", bd_status);
-
        if (!(bd_status & FEC_RBD_EMPTY)) {
+               debug("fec_recv: status 0x%04x len %u\n", bd_status,
+                       readw(&rbd->data_length) - 4);
                if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
                        ((readw(&rbd->data_length) - 4) > 14)) {
                        /*
@@ -837,6 +853,7 @@ static int fec_recv(struct eth_device *dev)
                         */
                        frame = (struct nbuf *)readl(&rbd->data_pointer);
                        frame_length = readw(&rbd->data_length) - 4;
+
                        /*
                         * Invalidate data cache over the buffer
                         */
@@ -851,8 +868,9 @@ static int fec_recv(struct eth_device *dev)
 #ifdef CONFIG_FEC_MXC_SWAP_PACKET
                        swap_packet((uint32_t *)frame->data, frame_length);
 #endif
-                       memcpy(buff, frame->data, frame_length);
-                       NetReceive(buff, frame_length);
+                       memcpy((void *)NetRxPackets[rx_idx], frame->data, frame_length);
+                       NetReceive(NetRxPackets[rx_idx], frame_length);
+                       rx_idx = (rx_idx + 1) % PKTBUFSRX;
                        len = frame_length;
                } else {
                        if (bd_status & FEC_RBD_ERR)
@@ -881,8 +899,8 @@ static int fec_recv(struct eth_device *dev)
 
                fec_rx_task_enable(fec);
                fec->rbd_index = (fec->rbd_index + 1) % FEC_RBD_NUM;
+               debug("fec_recv: stop\n");
        }
-       debug("fec_recv: stop\n");
 
        return len;
 }
@@ -975,23 +993,20 @@ static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
        int ret = 0;
 
        /* create and fill edev struct */
-       edev = (struct eth_device *)malloc(sizeof(struct eth_device));
+       edev = calloc(sizeof(struct eth_device), 1);
        if (!edev) {
                puts("fec_mxc: not enough malloc memory for eth_device\n");
                ret = -ENOMEM;
                goto err1;
        }
 
-       fec = (struct fec_priv *)malloc(sizeof(struct fec_priv));
+       fec = calloc(sizeof(struct fec_priv), 1);
        if (!fec) {
                puts("fec_mxc: not enough malloc memory for fec_priv\n");
                ret = -ENOMEM;
                goto err2;
        }
 
-       memset(edev, 0, sizeof(*edev));
-       memset(fec, 0, sizeof(*fec));
-
        ret = fec_alloc_descs(fec);
        if (ret)
                goto err3;
@@ -1035,7 +1050,10 @@ static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
        eth_register(edev);
 
        if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
-               debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
+               if (dev_id < 0)
+                       debug("got MAC address from fuse: %pM\n", ethaddr);
+               else
+                       debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
                memcpy(edev->enetaddr, ethaddr, 6);
                if (!getenv("ethaddr"))
                        eth_setenv_enetaddr("ethaddr", ethaddr);
index 0717cc6c3105c087b78fc3fc1bc63e9caced014f..44170174cf422c218fd01c7a374a755f9e47180a 100644 (file)
@@ -18,8 +18,6 @@
 #ifndef __FEC_MXC_H
 #define __FEC_MXC_H
 
-void imx_get_mac_from_fuse(int dev_id, unsigned char *mac);
-
 /**
  * Layout description of the FEC
  */
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
new file mode 100644 (file)
index 0000000..c72785c
--- /dev/null
@@ -0,0 +1,5 @@
+config PHYLIB
+       bool "Generic PHY support"
+
+config PHY_SMSC
+       bool "SMSC PHY support"
index df7e9450c2614a4040ced79d12d0e21238e5f689..d35e35f7eddf601d58980557b14bd1df65de982d 100644 (file)
@@ -44,7 +44,6 @@ static int genphy_config_advert(struct phy_device *phydev)
 
        /* Setup standard advertisement */
        oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
-
        if (adv < 0)
                return adv;
 
@@ -79,7 +78,6 @@ static int genphy_config_advert(struct phy_device *phydev)
        if (phydev->supported & (SUPPORTED_1000baseT_Half |
                                SUPPORTED_1000baseT_Full)) {
                oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
-
                if (adv < 0)
                        return adv;
 
@@ -112,7 +110,6 @@ static int genphy_config_advert(struct phy_device *phydev)
  */
 static int genphy_setup_forced(struct phy_device *phydev)
 {
-       int err;
        int ctl = 0;
 
        phydev->pause = phydev->asym_pause = 0;
@@ -125,9 +122,7 @@ static int genphy_setup_forced(struct phy_device *phydev)
        if (DUPLEX_FULL == phydev->duplex)
                ctl |= BMCR_FULLDPLX;
 
-       err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
-
-       return err;
+       return phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
 }
 
 
@@ -140,7 +135,6 @@ int genphy_restart_aneg(struct phy_device *phydev)
        int ctl;
 
        ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
-
        if (ctl < 0)
                return ctl;
 
@@ -149,9 +143,7 @@ int genphy_restart_aneg(struct phy_device *phydev)
        /* Don't isolate the PHY if we're negotiating */
        ctl &= ~(BMCR_ISOLATE);
 
-       ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
-
-       return ctl;
+       return phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
 }
 
 
@@ -205,13 +197,16 @@ int genphy_config_aneg(struct phy_device *phydev)
  */
 int genphy_update_link(struct phy_device *phydev)
 {
-       unsigned int mii_reg;
+       int mii_reg;
+       int bmcr;
 
        /*
         * Wait if the link is up, and autonegotiation is in progress
         * (ie - we're capable and it's not done)
         */
        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+       if (mii_reg < 0)
+               return mii_reg;
 
        /*
         * If we already saw the link up, and it hasn't gone down, then
@@ -220,6 +215,13 @@ int genphy_update_link(struct phy_device *phydev)
        if (phydev->link && mii_reg & BMSR_LSTATUS)
                return 0;
 
+       bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+       if (bmcr < 0)
+               return bmcr;
+
+       if (!(bmcr & BMCR_ANENABLE))
+               return 0;
+
        if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
                int i = 0;
 
@@ -246,12 +248,16 @@ int genphy_update_link(struct phy_device *phydev)
 
                        udelay(1000);   /* 1 ms */
                        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+                       if (mii_reg < 0)
+                               return mii_reg;
                }
                printf(" done\n");
                phydev->link = 1;
        } else {
                /* Read the link a second time to clear the latched state */
                mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+               if (mii_reg < 0)
+                       return mii_reg;
 
                if (mii_reg & BMSR_LSTATUS)
                        phydev->link = 1;
@@ -275,10 +281,14 @@ int genphy_parse_link(struct phy_device *phydev)
 {
        int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
 
+       if (mii_reg < 0)
+               return mii_reg;
+
        /* We're using autonegotiation */
        if (phydev->supported & SUPPORTED_Autoneg) {
+               int ret;
                u32 lpa = 0;
-               int gblpa = 0;
+               u32 gblpa = 0;
                u32 estatus = 0;
 
                /* Check for gigabit capability */
@@ -287,13 +297,17 @@ int genphy_parse_link(struct phy_device *phydev)
                        /* We want a list of states supported by
                         * both PHYs in the link
                         */
-                       gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
-                       if (gblpa < 0) {
+                       ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
+                       if (ret < 0) {
                                debug("Could not read MII_STAT1000. Ignoring gigabit capability\n");
-                               gblpa = 0;
+                               ret = 0;
                        }
-                       gblpa &= phy_read(phydev,
-                                       MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
+                       gblpa = ret;
+
+                       ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
+                       if (ret < 0)
+                               return ret;
+                       gblpa &= ret << 2;
                }
 
                /* Set the baseline so we only have to set them
@@ -313,8 +327,15 @@ int genphy_parse_link(struct phy_device *phydev)
                        return 0;
                }
 
-               lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
-               lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+               ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+               if (ret < 0)
+                       return ret;
+               lpa = ret;
+
+               ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+               if (ret < 0)
+                       return ret;
+               lpa &= ret;
 
                if (lpa & (LPA_100FULL | LPA_100HALF)) {
                        phydev->speed = SPEED_100;
@@ -336,6 +357,8 @@ int genphy_parse_link(struct phy_device *phydev)
                if ((mii_reg & BMSR_ESTATEN) && !(mii_reg & BMSR_ERCAP))
                        estatus = phy_read(phydev, MDIO_DEVAD_NONE,
                                           MII_ESTATUS);
+               if (estatus < 0)
+                       return estatus;
 
                if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_XHALF |
                                ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
@@ -345,7 +368,10 @@ int genphy_parse_link(struct phy_device *phydev)
                }
 
        } else {
-               u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+               int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+
+               if (bmcr < 0)
+                       return bmcr;
 
                phydev->speed = SPEED_10;
                phydev->duplex = DUPLEX_HALF;
@@ -375,7 +401,6 @@ int genphy_config(struct phy_device *phydev)
 
        /* Do we support autonegotiation? */
        val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
-
        if (val < 0)
                return val;
 
@@ -536,6 +561,69 @@ static struct phy_driver *get_phy_driver(struct phy_device *phydev,
        return generic_for_interface(interface);
 }
 
+static int aneg_enabled(struct phy_device *phydev)
+{
+       static const char *aneg = "_aneg";
+       char varname[strlen(phydev->bus->name) + strlen(aneg) + 1];
+
+       snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, aneg);
+       return getenv_yesno(varname);
+}
+
+static int phy_get_speed(struct phy_device *phydev)
+{
+       int ret;
+       static const char *aneg = "_speed";
+       char varname[strlen(phydev->bus->name) + strlen(aneg) + 1];
+       ulong val;
+
+       snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, aneg);
+
+       val = getenv_ulong(varname, 10, 100);
+       switch (val) {
+       case 1000:
+               ret = SPEED_1000;
+               break;
+       case 100:
+               ret = SPEED_100;
+               break;
+       case 10:
+               ret = SPEED_10;
+               break;
+       default:
+               printf("Improper setting '%s' for %s; assuming 100\n",
+                       getenv(varname), varname);
+               ret = SPEED_100;
+       }
+       return ret;
+}
+
+static int phy_get_duplex(struct phy_device *phydev)
+{
+       int ret = DUPLEX_FULL;
+       static const char *aneg = "_duplex";
+       char varname[strlen(phydev->bus->name) + strlen(aneg) + 4];
+       const char *val;
+
+       snprintf(varname, sizeof(varname), "%s%d%s",
+               phydev->bus->name, phydev->addr, aneg);
+
+       val = getenv(varname);
+       if (val != NULL) {
+               if (strcasecmp(val, "full") != 0) {
+                       if (strcasecmp(val, "half") == 0) {
+                               ret = DUPLEX_HALF;
+                       } else {
+                               printf("Improper setting '%s' for %s; assuming 'full'\n",
+                                       val, varname);
+                               printf("Expected one of: 'full', 'half'\n");
+                       }
+               }
+       }
+
+       return ret;
+}
+
 static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
                                            int phy_id,
                                            phy_interface_t interface)
@@ -557,14 +645,43 @@ static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
        dev->link = 1;
        dev->interface = interface;
 
-       dev->autoneg = AUTONEG_ENABLE;
-
        dev->addr = addr;
        dev->phy_id = phy_id;
        dev->bus = bus;
 
        dev->drv = get_phy_driver(dev, interface);
 
+       if (aneg_enabled(dev)) {
+               dev->autoneg = AUTONEG_ENABLE;
+       } else {
+               dev->autoneg = AUTONEG_DISABLE;
+               dev->speed = phy_get_speed(dev);
+               dev->duplex = phy_get_duplex(dev);
+
+               switch (dev->speed) {
+               case SPEED_1000:
+                       if (dev->duplex == DUPLEX_FULL)
+                               dev->supported &= SUPPORTED_1000baseT_Full;
+                       else
+                               dev->supported &= SUPPORTED_1000baseT_Half;
+                       break;
+               case SPEED_100:
+                       if (dev->duplex == DUPLEX_FULL)
+                               dev->supported &= SUPPORTED_100baseT_Full;
+                       else
+                               dev->supported &= SUPPORTED_100baseT_Half;
+                       break;
+               case SPEED_10:
+                       if (dev->duplex == DUPLEX_FULL)
+                               dev->supported &= SUPPORTED_10baseT_Full;
+                       else
+                               dev->supported &= SUPPORTED_10baseT_Half;
+                       break;
+               default:
+                       printf("Unsupported speed: %d\n", dev->speed);
+               }
+       }
+
        phy_probe(dev);
 
        bus->phymap[addr] = dev;
@@ -674,6 +791,7 @@ static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
 
 int phy_reset(struct phy_device *phydev)
 {
+       int err;
        int reg;
        int timeout = 500;
        int devad = MDIO_DEVAD_NONE;
@@ -696,9 +814,10 @@ int phy_reset(struct phy_device *phydev)
 
        reg |= BMCR_RESET;
 
-       if (phy_write(phydev, devad, MII_BMCR, reg) < 0) {
+       err = phy_write(phydev, devad, MII_BMCR, reg);
+       if (err < 0) {
                debug("PHY reset failed\n");
-               return -1;
+               return err;
        }
 
 #ifdef CONFIG_PHY_RESET_DELAY
@@ -709,19 +828,19 @@ int phy_reset(struct phy_device *phydev)
         * auto-clearing).  This should happen within 0.5 seconds per the
         * IEEE spec.
         */
-       while ((reg & BMCR_RESET) && timeout--) {
+       while ((reg & BMCR_RESET) && timeout-- >= 0) {
                reg = phy_read(phydev, devad, MII_BMCR);
 
                if (reg < 0) {
                        debug("PHY status read failed\n");
-                       return -1;
+                       return reg;
                }
                udelay(1000);
        }
 
        if (reg & BMCR_RESET) {
                puts("PHY reset timed out\n");
-               return -1;
+               return -ETIMEDOUT;
        }
 
        return 0;
index bfd9815abf9b68dcb52eb11cb5ed9ec38f559c97..1001d448524c90fda2a72c04abb15e48ebdab8c0 100644 (file)
  * Copyright (c) 2006 Herbert Valerio Riedel <hvr@gnu.org>
  */
 #include <miiphy.h>
+#include <errno.h>
+
+#define MII_LAN83C185_CTRL_STATUS      17 /* Mode/Status Register */
+#define MII_LAN83C185_EDPWRDOWN                (1 << 13) /* EDPWRDOWN */
+#define MII_LAN83C185_ENERGYON         (1 << 1)  /* ENERGYON */
 
 /* This code does not check the partner abilities. */
 static int smsc_parse_status(struct phy_device *phydev)
 {
-       int mii_reg;
+       int bmcr;
+       int aneg_exp;
+       int mii_adv;
+       int lpa;
+
+       aneg_exp = phy_read(phydev, MDIO_DEVAD_NONE, MII_EXPANSION);
+       if (aneg_exp < 0)
+               return aneg_exp;
+
+       if (aneg_exp & EXPANSION_MFAULTS) {
+               /* second read to clear latched status */
+               aneg_exp = phy_read(phydev, MDIO_DEVAD_NONE, MII_EXPANSION);
+               if (aneg_exp & EXPANSION_MFAULTS)
+                       return -EIO;
+       }
 
-       mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+       bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+       if (bmcr < 0)
+               return bmcr;
+       if (bmcr & BMCR_ANENABLE) {
+               lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+               if (lpa < 0)
+                       return lpa;
+               mii_adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+               if (mii_adv < 0)
+                       return mii_adv;
+               lpa &= mii_adv;
 
-       if (mii_reg & (BMSR_100FULL | BMSR_100HALF))
-               phydev->speed = SPEED_100;
-       else
-               phydev->speed = SPEED_10;
+               if (!(aneg_exp & EXPANSION_NWAY)) {
+                       /* parallel detection */
+                       phydev->duplex = DUPLEX_HALF;
+                       if (lpa & (LPA_100HALF | LPA_100FULL))
+                               phydev->speed = SPEED_100;
+                       else
+                               phydev->speed = SPEED_10;
+               }
 
-       if (mii_reg & (BMSR_10FULL | BMSR_100FULL))
-               phydev->duplex = DUPLEX_FULL;
-       else
-               phydev->duplex = DUPLEX_HALF;
+               if (lpa & (LPA_100FULL | LPA_100HALF)) {
+                       phydev->speed = SPEED_100;
+                       if (lpa & LPA_100FULL)
+                               phydev->duplex = DUPLEX_FULL;
+                       else
+                               phydev->duplex = DUPLEX_HALF;
+               } else if (lpa & (LPA_10FULL | LPA_10HALF)) {
+                       phydev->speed = SPEED_10;
+                       if (lpa & LPA_10FULL)
+                               phydev->duplex = DUPLEX_FULL;
+                       else
+                               phydev->duplex = DUPLEX_HALF;
+               } else {
+                       return -EINVAL;
+               }
+       } else {
+               if (bmcr & BMCR_SPEED100)
+                       phydev->speed = SPEED_100;
+               else
+                       phydev->speed = SPEED_10;
 
+               if (bmcr & BMCR_FULLDPLX)
+                       phydev->duplex = DUPLEX_FULL;
+               else
+                       phydev->duplex = DUPLEX_HALF;
+       }
        return 0;
 }
 
 static int smsc_startup(struct phy_device *phydev)
 {
-       genphy_update_link(phydev);
-       smsc_parse_status(phydev);
-       return 0;
+       int ret;
+
+       if (!phydev->link) {
+               /* Disable EDPD to wake up PHY */
+               ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_LAN83C185_CTRL_STATUS);
+
+               if (ret < 0)
+                       return ret;
+
+               if (ret & MII_LAN83C185_EDPWRDOWN) {
+                       ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_LAN83C185_CTRL_STATUS,
+                               ret & ~MII_LAN83C185_EDPWRDOWN);
+                       if (ret < 0)
+                               return ret;
+
+                       /* Sleep 64 ms to allow ~5 link test pulses to be sent */
+                       udelay(64 * 1000);
+               }
+       }
+
+       ret = genphy_update_link(phydev);
+       if (ret < 0)
+               return ret;
+       return smsc_parse_status(phydev);
+}
+
+static int smsc_mdix_setup(struct phy_device *phydev)
+{
+       int ret;
+       static const char *mdix = "_mdi";
+       char varname[strlen(phydev->bus->name) + strlen(mdix) + 1];
+       const char *val;
+
+       snprintf(varname, sizeof(varname), "%s%s", phydev->bus->name, mdix);
+
+       val = getenv(varname);
+       if (val) {
+               if (strcasecmp(val, "auto") == 0) {
+                       ret = 0;
+               } else if (strcasecmp(val, "mdix") == 0) {
+                       ret = 1;
+               } else if (strcasecmp(val, "mdi") == 0) {
+                       ret = 2;
+               } else {
+                       printf("Improper setting '%s' for %s\n", val, varname);
+                       printf("Expected one of: 'auto', 'mdi', 'mdix'\n");
+                       return -EINVAL;
+               }
+       } else {
+               ret = 0;
+       }
+       return ret;
+}
+
+static int smsc_config(struct phy_device *phydev)
+{
+       int mdix = smsc_mdix_setup(phydev);
+
+       if (mdix < 0) {
+               return mdix;
+       } else if (mdix) {
+               int ret = phy_write(phydev, MDIO_DEVAD_NONE, 0x1b,
+                               (1 << 15) | ((mdix & 1) << 13));
+               if (ret) {
+                       printf("Failed to setup MDI/MDIX mode: %d\n", ret);
+                       return ret;
+               }
+       }
+       return genphy_config_aneg(phydev);
 }
 
 static struct phy_driver lan8700_driver = {
@@ -64,8 +184,8 @@ static struct phy_driver lan8710_driver = {
        .uid = 0x0007c0f0,
        .mask = 0xffff0,
        .features = PHY_BASIC_FEATURES,
-       .config = &genphy_config_aneg,
-       .startup = &genphy_startup,
+       .config = &smsc_config,
+       .startup = &smsc_startup,
        .shutdown = &genphy_shutdown,
 };
 
index d43a5fedcc87ed782542b88191d4d162b869a481..10f7d889a3ad5db0bbdfb76578d8e5794a9bf6d7 100644 (file)
@@ -181,11 +181,11 @@ static void imx_serial_putc(const char c)
        /* Wait for Tx FIFO not full */
        while (base->uts & UTS_TXFULL);
 
-       base->utxd[0] = c;
-
        /* If \n, also do \r */
        if (c == '\n')
                serial_putc ('\r');
+
+       base->utxd[0] = c;
 }
 
 /*
index d6cf1d874a60c72c747489849bf58cffc915e57c..a9ca92107156e8901ae74f9ef0e6b0906fa380ee 100644 (file)
@@ -157,15 +157,15 @@ static int mxc_serial_getc(void)
 
 static void mxc_serial_putc(const char c)
 {
+       /* If \n, also do \r */
+       if (c == '\n')
+               serial_putc ('\r');
+
        __REG(UART_PHYS + UTXD) = c;
 
        /* wait for transmitter to be ready */
        while (!(__REG(UART_PHYS + UTS) & UTS_TXEMPTY))
                WATCHDOG_RESET();
-
-       /* If \n, also do \r */
-       if (c == '\n')
-               serial_putc ('\r');
 }
 
 /*
index 951dd3b25f2cf766df706a4fdbf86366dbff4e05..154be8cb7cbe1e01c31f9f18c917205546712c22 100644 (file)
 #define ANADIG_USB2_CHRG_DETECT_EN_B           0x00100000
 #define ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B     0x00080000
 
-#define ANADIG_USB2_PLL_480_CTRL_BYPASS                0x00010000
-#define ANADIG_USB2_PLL_480_CTRL_ENABLE                0x00002000
-#define ANADIG_USB2_PLL_480_CTRL_POWER         0x00001000
-#define ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS   0x00000040
+#define ANADIG_USB_PLL_480_CTRL_BYPASS         0x00010000
+#define ANADIG_USB_PLL_480_CTRL_ENABLE         0x00002000
+#define ANADIG_USB_PLL_480_CTRL_POWER          0x00001000
+#define ANADIG_USB_PLL_480_CTRL_EN_USB_CLKS    0x00000040
 
 
 #define UCTRL_OVER_CUR_POL     (1 << 8) /* OTG Polarity of Overcurrent */
@@ -104,12 +104,12 @@ static void usb_power_config(int index)
                     ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B,
                     chrg_detect);
 
-       __raw_writel(ANADIG_USB2_PLL_480_CTRL_BYPASS,
+       __raw_writel(ANADIG_USB_PLL_480_CTRL_BYPASS,
                     pll_480_ctrl_clr);
 
-       __raw_writel(ANADIG_USB2_PLL_480_CTRL_ENABLE |
-                    ANADIG_USB2_PLL_480_CTRL_POWER |
-                    ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
+       __raw_writel(ANADIG_USB_PLL_480_CTRL_ENABLE |
+                    ANADIG_USB_PLL_480_CTRL_POWER |
+                    ANADIG_USB_PLL_480_CTRL_EN_USB_CLKS,
                     pll_480_ctrl_set);
 }
 
index 5873531953316a25799c020206328bd84280b97d..7e249f67ab40a572888591f96700e2a1ad32a6e1 100644 (file)
@@ -4,26 +4,27 @@
  * (C) Copyright 2010
  * Stefano Babic, DENX Software Engineering, sbabic@denx.de
  *
- * Linux IPU driver for MX51:
+ * Linux IPU driver
  *
- * (C) Copyright 2005-2010 Freescale Semiconductor, Inc.
+ * (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
 /* #define DEBUG */
 #include <common.h>
+#include <ipu.h>
 #include <linux/types.h>
 #include <linux/err.h>
 #include <asm/io.h>
 #include <asm/errno.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/crm_regs.h>
-#include "ipu.h"
+#include <asm/arch/clock.h>
+
 #include "ipu_regs.h"
 
-extern struct mxc_ccm_reg *mxc_ccm;
-extern u32 *ipu_cpmem_base;
+static struct mxc_ccm_reg __maybe_unused *mxc_ccm = (void *)CCM_BASE_ADDR;
 
 struct ipu_ch_param_word {
        uint32_t data[5];
@@ -37,202 +38,104 @@ struct ipu_ch_param {
 #define ipu_ch_param_addr(ch) (((struct ipu_ch_param *)ipu_cpmem_base) + (ch))
 
 #define _param_word(base, w) \
-       (((struct ipu_ch_param *)(base))->word[(w)].data)
+       (((struct ipu_ch_param *)(base))->word[w].data)
 
-#define ipu_ch_param_set_field(base, w, bit, size, v) { \
-       int i = (bit) / 32; \
-       int off = (bit) % 32; \
-       _param_word(base, w)[i] |= (v) << off; \
-       if (((bit) + (size) - 1) / 32 > i) { \
+#define ipu_ch_param_set_field(base, w, bit, size, v) {                        \
+       int i = (bit) / 32;                                             \
+       int off = (bit) % 32;                                           \
+       _param_word(base, w)[i] |= (v) << off;                          \
+       if (((bit) + (size) - 1) / 32 > i) {                            \
                _param_word(base, w)[i + 1] |= (v) >> (off ? (32 - off) : 0); \
-       } \
+       }                                                               \
 }
 
-#define ipu_ch_param_mod_field(base, w, bit, size, v) { \
-       int i = (bit) / 32; \
-       int off = (bit) % 32; \
-       u32 mask = (1UL << size) - 1; \
-       u32 temp = _param_word(base, w)[i]; \
-       temp &= ~(mask << off); \
-       _param_word(base, w)[i] = temp | (v) << off; \
-       if (((bit) + (size) - 1) / 32 > i) { \
-               temp = _param_word(base, w)[i + 1]; \
-               temp &= ~(mask >> (32 - off)); \
-               _param_word(base, w)[i + 1] = \
+#define ipu_ch_param_mod_field(base, w, bit, size, v) {                \
+       int i = (bit) / 32;                                     \
+       int off = (bit) % 32;                                   \
+       u32 mask = (1UL << size) - 1;                           \
+       u32 temp = _param_word(base, w)[i];                     \
+       temp &= ~(mask << off);                                 \
+       _param_word(base, w)[i] = temp | (v) << off;            \
+       if (((bit) + (size) - 1) / 32 > i) {                    \
+               temp = _param_word(base, w)[i + 1];             \
+               temp &= ~(mask >> (32 - off));                  \
+               _param_word(base, w)[i + 1] =                   \
                        temp | ((v) >> (off ? (32 - off) : 0)); \
-       } \
+       }                                                       \
 }
 
-#define ipu_ch_param_read_field(base, w, bit, size) ({ \
-       u32 temp2; \
-       int i = (bit) / 32; \
-       int off = (bit) % 32; \
-       u32 mask = (1UL << size) - 1; \
-       u32 temp1 = _param_word(base, w)[i]; \
-       temp1 = mask & (temp1 >> off); \
-       if (((bit)+(size) - 1) / 32 > i) { \
-               temp2 = _param_word(base, w)[i + 1]; \
-               temp2 &= mask >> (off ? (32 - off) : 0); \
-               temp1 |= temp2 << (off ? (32 - off) : 0); \
-       } \
-       temp1; \
+#define ipu_ch_param_read_field(base, w, bit, size) ({         \
+       u32 temp2;                                              \
+       int i = (bit) / 32;                                     \
+       int off = (bit) % 32;                                   \
+       u32 mask = (1UL << size) - 1;                           \
+       u32 temp1 = _param_word(base, w)[i];                    \
+       temp1 = mask & (temp1 >> off);                          \
+       if (((bit)+(size) - 1) / 32 > i) {                      \
+               temp2 = _param_word(base, w)[i + 1];            \
+               temp2 &= mask >> (off ? (32 - off) : 0);        \
+               temp1 |= temp2 << (off ? (32 - off) : 0);       \
+       }                                                       \
+       temp1;                                                  \
 })
 
-#define IPU_SW_RST_TOUT_USEC   (10000)
-
-void clk_enable(struct clk *clk)
-{
-       if (clk) {
-               if (clk->usecount++ == 0) {
-                       clk->enable(clk);
-               }
-       }
-}
-
-void clk_disable(struct clk *clk)
-{
-       if (clk) {
-               if (!(--clk->usecount)) {
-                       if (clk->disable)
-                               clk->disable(clk);
-               }
-       }
-}
-
-int clk_get_usecount(struct clk *clk)
-{
-       if (clk == NULL)
-               return 0;
-
-       return clk->usecount;
-}
-
-u32 clk_get_rate(struct clk *clk)
-{
-       if (!clk)
-               return 0;
-
-       return clk->rate;
-}
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-       if (!clk)
-               return 0;
-
-       return clk->parent;
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       if (clk && clk->set_rate)
-               clk->set_rate(clk, rate);
-       return clk->rate;
-}
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       if (clk == NULL || !clk->round_rate)
-               return 0;
-
-       return clk->round_rate(clk, rate);
-}
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       clk->parent = parent;
-       if (clk->set_parent)
-               return clk->set_parent(clk, parent);
-       return 0;
-}
+#define IPU_SW_RST_TOUT_USEC   10000
 
 static int clk_ipu_enable(struct clk *clk)
 {
-       u32 reg;
-
-       reg = __raw_readl(clk->enable_reg);
-       reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift;
-       __raw_writel(reg, clk->enable_reg);
-
-#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
-       /* Handshake with IPU when certain clock rates are changed. */
-       reg = __raw_readl(&mxc_ccm->ccdr);
-       reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
-       __raw_writel(reg, &mxc_ccm->ccdr);
-
-       /* Handshake with IPU when LPM is entered as its enabled. */
-       reg = __raw_readl(&mxc_ccm->clpcr);
-       reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
-       __raw_writel(reg, &mxc_ccm->clpcr);
-#endif
+       ipu_clk_enable();
        return 0;
 }
 
 static void clk_ipu_disable(struct clk *clk)
 {
-       u32 reg;
-
-       reg = __raw_readl(clk->enable_reg);
-       reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift);
-       __raw_writel(reg, clk->enable_reg);
-
-#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
-       /*
-        * No handshake with IPU whe dividers are changed
-        * as its not enabled.
-        */
-       reg = __raw_readl(&mxc_ccm->ccdr);
-       reg |= MXC_CCM_CCDR_IPU_HS_MASK;
-       __raw_writel(reg, &mxc_ccm->ccdr);
-
-       /* No handshake with IPU when LPM is entered as its not enabled. */
-       reg = __raw_readl(&mxc_ccm->clpcr);
-       reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
-       __raw_writel(reg, &mxc_ccm->clpcr);
-#endif
+       ipu_clk_disable();
 }
 
-
 static struct clk ipu_clk = {
        .name = "ipu_clk",
        .rate = CONFIG_IPUV3_CLK,
-#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
-       .enable_reg = (u32 *)(CCM_BASE_ADDR +
-               offsetof(struct mxc_ccm_reg, CCGR5)),
-       .enable_shift = MXC_CCM_CCGR5_IPU_OFFSET,
-#else
-       .enable_reg = (u32 *)(CCM_BASE_ADDR +
-               offsetof(struct mxc_ccm_reg, CCGR3)),
-       .enable_shift = MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET,
-#endif
        .enable = clk_ipu_enable,
        .disable = clk_ipu_disable,
-       .usecount = 0,
 };
 
+static int clk_ldb_enable(struct clk *clk)
+{
+       ldb_clk_enable(0);
+       ldb_clk_enable(1);
+       return 0;
+}
+
+static void clk_ldb_disable(struct clk *clk)
+{
+       ldb_clk_disable(0);
+       ldb_clk_disable(1);
+}
+
 static struct clk ldb_clk = {
        .name = "ldb_clk",
        .rate = 65000000,
-       .usecount = 0,
+       .enable = clk_ldb_enable,
+       .disable = clk_ldb_disable,
 };
 
 /* Globals */
 struct clk *g_ipu_clk;
 struct clk *g_ldb_clk;
-unsigned char g_ipu_clk_enabled;
 struct clk *g_di_clk[2];
 struct clk *g_pixel_clk[2];
 unsigned char g_dc_di_assignment[10];
-uint32_t g_channel_init_mask;
-uint32_t g_channel_enable_mask;
+int g_ipu_clk_enabled;
+u32 *ipu_dc_tmpl_reg;
 
+static uint32_t g_channel_init_mask;
+static uint32_t g_channel_enable_mask;
 static int ipu_dc_use_count;
 static int ipu_dp_use_count;
 static int ipu_dmfc_use_count;
 static int ipu_di_use_count[2];
 
-u32 *ipu_cpmem_base;
-u32 *ipu_dc_tmpl_reg;
+static u32 *ipu_cpmem_base;
 
 /* Static functions */
 
@@ -282,13 +185,13 @@ static unsigned long ipu_pixel_clk_round_rate(struct clk *clk,
        unsigned long rate)
 {
        u32 div, div1;
-       u32 tmp;
+       u64 tmp;
        /*
         * Calculate divider
         * Fractional part is 4 bits,
         * so simply multiply by 2^4 to get fractional part.
         */
-       tmp = (clk->parent->rate * 16);
+       tmp = (u64)clk->parent->rate * 16;
        div = tmp / rate;
 
        if (div < 0x10)            /* Min DI disp clock divider is 1 */
@@ -302,19 +205,32 @@ static unsigned long ipu_pixel_clk_round_rate(struct clk *clk,
                else
                        div &= 0xFF8;
        }
-       return (clk->parent->rate * 16) / div;
+       tmp /= div;
+#if 1
+       debug("%s: requested rate: %lu.%03luMHz parent_rate: %lu.%03luMHz actual rate: %llu.%03lluMHz div: %u.%u\n", __func__,
+               rate / 1000000, rate / 1000 % 1000,
+               clk->parent->rate / 1000000, clk->parent->rate / 1000 % 1000,
+               tmp / 1000000, tmp / 1000 % 1000, div / 16, div % 16);
+#endif
+       return tmp;
 }
 
 static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
 {
-       u32 div = (clk->parent->rate * 16) / rate;
+       u32 div = ((u64)clk->parent->rate * 16) / rate;
+
+       debug("%s: parent_rate: %lu.%03luMHz actual rate: %lu.%03luMHz div: %u.%u\n", __func__,
+               clk->parent->rate / 1000000, clk->parent->rate / 1000 % 1000,
+               rate / 1000000, rate / 1000 % 1000, div / 16, div % 16);
 
        __raw_writel(div, DI_BS_CLKGEN0(clk->id));
 
        /* Setup pixel clock timing */
        __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id));
 
-       clk->rate = (clk->parent->rate * 16) / div;
+       clk->rate = ((u64)clk->parent->rate * 16) / div;
+       debug("%s: pix_clk=%lu.%03luMHz\n", __func__,
+               clk->rate / 1000000, clk->rate / 1000 % 1000);
        return 0;
 }
 
@@ -332,47 +248,84 @@ static void ipu_pixel_clk_disable(struct clk *clk)
        u32 disp_gen = __raw_readl(IPU_DISP_GEN);
        disp_gen &= clk->id ? ~DI1_COUNTER_RELEASE : ~DI0_COUNTER_RELEASE;
        __raw_writel(disp_gen, IPU_DISP_GEN);
-
 }
 
 static int ipu_pixel_clk_set_parent(struct clk *clk, struct clk *parent)
 {
-       u32 di_gen = __raw_readl(DI_GENERAL(clk->id));
+       int ret;
+       u32 di_gen;
+
+       ret = clk_enable(clk);
+       if (ret)
+               return ret;
+
+       di_gen = __raw_readl(DI_GENERAL(clk->id));
 
        if (parent == g_ipu_clk)
                di_gen &= ~DI_GEN_DI_CLK_EXT;
        else if (!IS_ERR(g_di_clk[clk->id]) && parent == g_ldb_clk)
                di_gen |= DI_GEN_DI_CLK_EXT;
        else
-               return -EINVAL;
+               goto err;
 
+       ret = clk_enable(parent);
+       if (ret)
+               goto err;
        __raw_writel(di_gen, DI_GENERAL(clk->id));
        ipu_pixel_clk_recalc(clk);
-       return 0;
+       clk->disable(clk->parent);
+       clk->parent = parent;
+err:
+       clk_disable(clk);
+       return ret;
 }
 
 static struct clk pixel_clk[] = {
        {
-       .name = "pixel_clk",
-       .id = 0,
-       .recalc = ipu_pixel_clk_recalc,
-       .set_rate = ipu_pixel_clk_set_rate,
-       .round_rate = ipu_pixel_clk_round_rate,
-       .set_parent = ipu_pixel_clk_set_parent,
-       .enable = ipu_pixel_clk_enable,
-       .disable = ipu_pixel_clk_disable,
-       .usecount = 0,
+               .name = "pixel_clk",
+               .id = 0,
+               .recalc = ipu_pixel_clk_recalc,
+               .set_rate = ipu_pixel_clk_set_rate,
+               .round_rate = ipu_pixel_clk_round_rate,
+               .set_parent = ipu_pixel_clk_set_parent,
+               .enable = ipu_pixel_clk_enable,
+               .disable = ipu_pixel_clk_disable,
        },
        {
-       .name = "pixel_clk",
-       .id = 1,
-       .recalc = ipu_pixel_clk_recalc,
-       .set_rate = ipu_pixel_clk_set_rate,
-       .round_rate = ipu_pixel_clk_round_rate,
-       .set_parent = ipu_pixel_clk_set_parent,
-       .enable = ipu_pixel_clk_enable,
-       .disable = ipu_pixel_clk_disable,
-       .usecount = 0,
+               .name = "pixel_clk",
+               .id = 1,
+               .recalc = ipu_pixel_clk_recalc,
+               .set_rate = ipu_pixel_clk_set_rate,
+               .round_rate = ipu_pixel_clk_round_rate,
+               .set_parent = ipu_pixel_clk_set_parent,
+               .enable = ipu_pixel_clk_enable,
+               .disable = ipu_pixel_clk_disable,
+       },
+};
+
+static int clk_ipu_di_enable(struct clk *clk)
+{
+       ipu_di_clk_enable(clk->id);
+       return 0;
+}
+
+static void clk_ipu_di_disable(struct clk *clk)
+{
+       ipu_di_clk_disable(clk->id);
+}
+
+static struct clk di_clk[] = {
+       {
+               .name = "ipu_di_clk",
+               .id = 0,
+               .enable = clk_ipu_di_enable,
+               .disable = clk_ipu_di_disable,
+       },
+       {
+               .name = "ipu_di_clk",
+               .id = 1,
+               .enable = clk_ipu_di_enable,
+               .disable = clk_ipu_di_disable,
        },
 };
 
@@ -408,48 +361,69 @@ static void ipu_reset(void)
  *
  * @return      Returns 0 on success or negative error code on error
  */
-int ipu_probe(void)
+int ipu_probe(int di, ipu_di_clk_parent_t di_clk_parent, int di_clk_val)
 {
-       unsigned long ipu_base;
+       int ret;
+       void *ipu_base;
+       unsigned long start;
 #if defined CONFIG_MX51
        u32 temp;
-
        u32 *reg_hsc_mcd = (u32 *)MIPI_HSC_BASE_ADDR;
        u32 *reg_hsc_mxt_conf = (u32 *)(MIPI_HSC_BASE_ADDR + 0x800);
 
         __raw_writel(0xF00, reg_hsc_mcd);
 
-       /* CSI mode reserved*/
+       /* CSI mode reserved */
        temp = __raw_readl(reg_hsc_mxt_conf);
         __raw_writel(temp | 0x0FF, reg_hsc_mxt_conf);
 
        temp = __raw_readl(reg_hsc_mxt_conf);
        __raw_writel(temp | 0x10000, reg_hsc_mxt_conf);
 #endif
-
-       ipu_base = IPU_CTRL_BASE_ADDR;
-       ipu_cpmem_base = (u32 *)(ipu_base + IPU_CPMEM_REG_BASE);
-       ipu_dc_tmpl_reg = (u32 *)(ipu_base + IPU_DC_TMPL_REG_BASE);
+       ipu_base = (void *)IPU_SOC_BASE_ADDR;
+       /* base fixup */
+       if (gd->arch.ipu_hw_rev == IPUV3_HW_REV_IPUV3H) /* IPUv3H */
+               ipu_base += IPUV3H_REG_BASE;
+       else if (gd->arch.ipu_hw_rev == IPUV3_HW_REV_IPUV3M)    /* IPUv3M */
+               ipu_base += IPUV3M_REG_BASE;
+       else                    /* IPUv3D, v3E, v3EX */
+               ipu_base += IPUV3DEX_REG_BASE;
+       ipu_cpmem_base = ipu_base + IPU_CPMEM_REG_BASE;
+       ipu_dc_tmpl_reg = ipu_base + IPU_DC_TMPL_REG_BASE;
+
+       printf("IPU HW Rev: %d\n", gd->arch.ipu_hw_rev);
 
        g_pixel_clk[0] = &pixel_clk[0];
        g_pixel_clk[1] = &pixel_clk[1];
 
+       g_di_clk[0] = &di_clk[0];
+       g_di_clk[1] = &di_clk[1];
+       g_di_clk[di]->rate = di_clk_val;
+
        g_ipu_clk = &ipu_clk;
        debug("ipu_clk = %u\n", clk_get_rate(g_ipu_clk));
+
        g_ldb_clk = &ldb_clk;
        debug("ldb_clk = %u\n", clk_get_rate(g_ldb_clk));
-       ipu_reset();
 
-       clk_set_parent(g_pixel_clk[0], g_ipu_clk);
-       clk_set_parent(g_pixel_clk[1], g_ipu_clk);
-       clk_enable(g_ipu_clk);
+       ret = clk_enable(g_ipu_clk);
+       if (ret)
+               return ret;
+       ipu_reset();
 
-       g_di_clk[0] = NULL;
-       g_di_clk[1] = NULL;
+       if (di_clk_parent == DI_PCLK_LDB) {
+               clk_set_parent(g_pixel_clk[di], g_ldb_clk);
+       } else {
+               clk_set_parent(g_pixel_clk[0], g_ipu_clk);
+               clk_set_parent(g_pixel_clk[1], g_ipu_clk);
+       }
 
        __raw_writel(0x807FFFFF, IPU_MEM_RST);
-       while (__raw_readl(IPU_MEM_RST) & 0x80000000)
-               ;
+       start = get_timer_masked();
+       while (__raw_readl(IPU_MEM_RST) & 0x80000000) {
+               if (get_timer(start) > CONFIG_SYS_HZ)
+                       return -ETIME;
+       }
 
        ipu_init_dc_mappings();
 
@@ -474,37 +448,37 @@ int ipu_probe(void)
 
 void ipu_dump_registers(void)
 {
-       debug("IPU_CONF = \t0x%08X\n", __raw_readl(IPU_CONF));
-       debug("IDMAC_CONF = \t0x%08X\n", __raw_readl(IDMAC_CONF));
-       debug("IDMAC_CHA_EN1 = \t0x%08X\n",
+       debug("IPU_CONF             0x%08X\n", __raw_readl(IPU_CONF));
+       debug("IDMAC_CONF           0x%08X\n", __raw_readl(IDMAC_CONF));
+       debug("IDMAC_CHA_EN1        0x%08X\n",
               __raw_readl(IDMAC_CHA_EN(0)));
-       debug("IDMAC_CHA_EN2 = \t0x%08X\n",
+       debug("IDMAC_CHA_EN2        0x%08X\n",
               __raw_readl(IDMAC_CHA_EN(32)));
-       debug("IDMAC_CHA_PRI1 = \t0x%08X\n",
+       debug("IDMAC_CHA_PRI1       0x%08X\n",
               __raw_readl(IDMAC_CHA_PRI(0)));
-       debug("IDMAC_CHA_PRI2 = \t0x%08X\n",
+       debug("IDMAC_CHA_PRI2       0x%08X\n",
               __raw_readl(IDMAC_CHA_PRI(32)));
-       debug("IPU_CHA_DB_MODE_SEL0 = \t0x%08X\n",
+       debug("IPU_CHA_DB_MODE_SEL0 0x%08X\n",
               __raw_readl(IPU_CHA_DB_MODE_SEL(0)));
-       debug("IPU_CHA_DB_MODE_SEL1 = \t0x%08X\n",
+       debug("IPU_CHA_DB_MODE_SEL1 0x%08X\n",
               __raw_readl(IPU_CHA_DB_MODE_SEL(32)));
-       debug("DMFC_WR_CHAN = \t0x%08X\n",
+       debug("DMFC_WR_CHAN         0x%08X\n",
               __raw_readl(DMFC_WR_CHAN));
-       debug("DMFC_WR_CHAN_DEF = \t0x%08X\n",
+       debug("DMFC_WR_CHAN_DEF     0x%08X\n",
               __raw_readl(DMFC_WR_CHAN_DEF));
-       debug("DMFC_DP_CHAN = \t0x%08X\n",
+       debug("DMFC_DP_CHAN         0x%08X\n",
               __raw_readl(DMFC_DP_CHAN));
-       debug("DMFC_DP_CHAN_DEF = \t0x%08X\n",
+       debug("DMFC_DP_CHAN_DEF     0x%08X\n",
               __raw_readl(DMFC_DP_CHAN_DEF));
-       debug("DMFC_IC_CTRL = \t0x%08X\n",
+       debug("DMFC_IC_CTRL         0x%08X\n",
               __raw_readl(DMFC_IC_CTRL));
-       debug("IPU_FS_PROC_FLOW1 = \t0x%08X\n",
+       debug("IPU_FS_PROC_FLOW1    0x%08X\n",
               __raw_readl(IPU_FS_PROC_FLOW1));
-       debug("IPU_FS_PROC_FLOW2 = \t0x%08X\n",
+       debug("IPU_FS_PROC_FLOW2    0x%08X\n",
               __raw_readl(IPU_FS_PROC_FLOW2));
-       debug("IPU_FS_PROC_FLOW3 = \t0x%08X\n",
+       debug("IPU_FS_PROC_FLOW3    0x%08X\n",
               __raw_readl(IPU_FS_PROC_FLOW3));
-       debug("IPU_FS_DISP_FLOW1 = \t0x%08X\n",
+       debug("IPU_FS_DISP_FLOW1    0x%08X\n",
               __raw_readl(IPU_FS_DISP_FLOW1));
 }
 
@@ -578,7 +552,6 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
                break;
        default:
                printf("Missing channel initialization\n");
-               break;
        }
 
        /* Enable IPU sub module */
@@ -591,9 +564,11 @@ int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params)
                ipu_conf |= IPU_CONF_DMFC_EN;
        if (ipu_di_use_count[0] == 1) {
                ipu_conf |= IPU_CONF_DI0_EN;
+               clk_enable(g_di_clk[0]);
        }
        if (ipu_di_use_count[1] == 1) {
                ipu_conf |= IPU_CONF_DI1_EN;
+               clk_enable(g_di_clk[1]);
        }
 
        __raw_writel(ipu_conf, IPU_CONF);
@@ -628,8 +603,7 @@ void ipu_uninit_channel(ipu_channel_t channel)
 
        if (idma_is_set(IDMAC_CHA_EN, in_dma) ||
            idma_is_set(IDMAC_CHA_EN, out_dma)) {
-               printf(
-                       "Channel %d is not disabled, disable first\n",
+               printf("Channel %d is not disabled, disable first\n",
                        IPU_CHAN_ID(channel));
                return;
        }
@@ -675,20 +649,24 @@ void ipu_uninit_channel(ipu_channel_t channel)
                ipu_conf &= ~IPU_CONF_DP_EN;
        if (ipu_dmfc_use_count == 0)
                ipu_conf &= ~IPU_CONF_DMFC_EN;
-       if (ipu_di_use_count[0] == 0) {
+       if (ipu_di_use_count[0] == 0 && ipu_conf & IPU_CONF_DI0_EN) {
                ipu_conf &= ~IPU_CONF_DI0_EN;
+               clk_disable(g_di_clk[0]);
        }
-       if (ipu_di_use_count[1] == 0) {
+       if (ipu_di_use_count[1] == 0 && ipu_conf & IPU_CONF_DI1_EN) {
                ipu_conf &= ~IPU_CONF_DI1_EN;
+               clk_disable(g_di_clk[1]);
        }
 
        __raw_writel(ipu_conf, IPU_CONF);
 
+       /* clear interrupt status */
+       __raw_writel(__raw_readl(IPU_STAT), IPU_STAT);
+
        if (ipu_conf == 0) {
                clk_disable(g_ipu_clk);
                g_ipu_clk_enabled = 0;
        }
-
 }
 
 static inline void ipu_ch_param_dump(int ch)
@@ -763,91 +741,88 @@ static void ipu_ch_param_init(int ch,
 {
        uint32_t u_offset = 0;
        uint32_t v_offset = 0;
-       struct ipu_ch_param params;
-
-       memset(&params, 0, sizeof(params));
 
-       ipu_ch_param_set_field(&params, 0, 125, 13, width - 1);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 125, 13, width - 1);
 
        if ((ch == 8) || (ch == 9) || (ch == 10)) {
-               ipu_ch_param_set_field(&params, 0, 138, 12, (height / 2) - 1);
-               ipu_ch_param_set_field(&params, 1, 102, 14, (stride * 2) - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 138, 12, (height / 2) - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 102, 14, (stride * 2) - 1);
        } else {
-               ipu_ch_param_set_field(&params, 0, 138, 12, height - 1);
-               ipu_ch_param_set_field(&params, 1, 102, 14, stride - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 138, 12, height - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 102, 14, stride - 1);
        }
 
-       ipu_ch_param_set_field(&params, 1, 0, 29, addr0 >> 3);
-       ipu_ch_param_set_field(&params, 1, 29, 29, addr1 >> 3);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 0, 29, addr0 >> 3);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 29, 29, addr1 >> 3);
 
        switch (pixel_fmt) {
        case IPU_PIX_FMT_GENERIC:
                /*Represents 8-bit Generic data */
-               ipu_ch_param_set_field(&params, 0, 107, 3, 5);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 6);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 63);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 5);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 6);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 63);    /* burst size */
 
                break;
        case IPU_PIX_FMT_GENERIC_32:
                /*Represents 32-bit Generic data */
                break;
        case IPU_PIX_FMT_RGB565:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 3);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);    /* burst size */
 
-               ipu_ch_params_set_packing(&params, 5, 0, 6, 5, 5, 11, 8, 16);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 5, 0, 6, 5, 5, 11, 8, 16);
                break;
        case IPU_PIX_FMT_BGR24:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 1);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 19);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 1);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 19);    /* burst size */
 
-               ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 0, 8, 8, 8, 16, 8, 24);
                break;
        case IPU_PIX_FMT_RGB24:
        case IPU_PIX_FMT_YUV444:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 1);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 19);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 1);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 19);    /* burst size */
 
-               ipu_ch_params_set_packing(&params, 8, 16, 8, 8, 8, 0, 8, 24);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 16, 8, 8, 8, 0, 8, 24);
                break;
        case IPU_PIX_FMT_BGRA32:
        case IPU_PIX_FMT_BGR32:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 0);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);    /* burst size */
 
-               ipu_ch_params_set_packing(&params, 8, 8, 8, 16, 8, 24, 8, 0);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 8, 8, 16, 8, 24, 8, 0);
                break;
        case IPU_PIX_FMT_RGBA32:
        case IPU_PIX_FMT_RGB32:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 0);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);    /* burst size */
 
-               ipu_ch_params_set_packing(&params, 8, 24, 8, 16, 8, 8, 8, 0);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 24, 8, 16, 8, 8, 8, 0);
                break;
        case IPU_PIX_FMT_ABGR32:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 0);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 7);   /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 0);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 7);     /* pix format */
 
-               ipu_ch_params_set_packing(&params, 8, 0, 8, 8, 8, 16, 8, 24);
+               ipu_ch_params_set_packing(ipu_ch_param_addr(ch), 8, 0, 8, 8, 8, 16, 8, 24);
                break;
        case IPU_PIX_FMT_UYVY:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 0xA); /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 15);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 3);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 0xA);   /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);    /* burst size */
                break;
        case IPU_PIX_FMT_YUYV:
-               ipu_ch_param_set_field(&params, 0, 107, 3, 3);  /* bits/pixel */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 0x8); /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 107, 3, 3);    /* bits/pixel */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 0x8);   /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);    /* burst size */
                break;
        case IPU_PIX_FMT_YUV420P2:
        case IPU_PIX_FMT_YUV420P:
-               ipu_ch_param_set_field(&params, 1, 85, 4, 2);   /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 2);     /* pix format */
 
                if (uv_stride < stride / 2)
                        uv_stride = stride / 2;
@@ -856,16 +831,16 @@ static void ipu_ch_param_init(int ch,
                v_offset = u_offset + (uv_stride * height / 2);
                /* burst size */
                if ((ch == 8) || (ch == 9) || (ch == 10)) {
-                       ipu_ch_param_set_field(&params, 1, 78, 7, 15);
+                       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 15);
                        uv_stride = uv_stride*2;
                } else {
-                       ipu_ch_param_set_field(&params, 1, 78, 7, 31);
+                       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);
                }
                break;
        case IPU_PIX_FMT_YVU422P:
                /* BPP & pixel format */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 1);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 1);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);    /* burst size */
 
                if (uv_stride < stride / 2)
                        uv_stride = stride / 2;
@@ -875,8 +850,8 @@ static void ipu_ch_param_init(int ch,
                break;
        case IPU_PIX_FMT_YUV422P:
                /* BPP & pixel format */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 1);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 1);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);    /* burst size */
 
                if (uv_stride < stride / 2)
                        uv_stride = stride / 2;
@@ -886,19 +861,19 @@ static void ipu_ch_param_init(int ch,
                break;
        case IPU_PIX_FMT_NV12:
                /* BPP & pixel format */
-               ipu_ch_param_set_field(&params, 1, 85, 4, 4);   /* pix format */
-               ipu_ch_param_set_field(&params, 1, 78, 7, 31);  /* burst size */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 85, 4, 4);     /* pix format */
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 78, 7, 31);    /* burst size */
                uv_stride = stride;
                u_offset = (u == 0) ? stride * height : u;
                break;
        default:
-               puts("mxc ipu: unimplemented pixel format\n");
-               break;
+               printf("mxc ipu: unimplemented pixel format: %08x\n",
+                       pixel_fmt);
        }
 
 
        if (uv_stride)
-               ipu_ch_param_set_field(&params, 1, 128, 14, uv_stride - 1);
+               ipu_ch_param_set_field(ipu_ch_param_addr(ch), 1, 128, 14, uv_stride - 1);
 
        /* Get the uv offset from user when need cropping */
        if (u || v) {
@@ -912,11 +887,10 @@ static void ipu_ch_param_init(int ch,
        if (v_offset/8 > 0x3fffff)
                puts("The value of V offset exceeds IPU limitation\n");
 
-       ipu_ch_param_set_field(&params, 0, 46, 22, u_offset / 8);
-       ipu_ch_param_set_field(&params, 0, 68, 22, v_offset / 8);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 46, 22, u_offset / 8);
+       ipu_ch_param_set_field(ipu_ch_param_addr(ch), 0, 68, 22, v_offset / 8);
 
        debug("initializing idma ch %d @ %p\n", ch, ipu_ch_param_addr(ch));
-       memcpy(ipu_ch_param_addr(ch), &params, sizeof(params));
 };
 
 /*
@@ -968,8 +942,7 @@ int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type,
                stride = width * bytes_per_pixel(pixel_fmt);
 
        if (stride % 4) {
-               printf(
-                       "Stride not 32-bit aligned, stride = %d\n", stride);
+               printf("Stride %d not 32-bit aligned\n", stride);
                return -EINVAL;
        }
        /* Build parameter memory data for DMA channel */
@@ -1031,8 +1004,12 @@ int32_t ipu_enable_channel(ipu_channel_t channel)
        }
 
        if ((channel == MEM_DC_SYNC) || (channel == MEM_BG_SYNC) ||
-           (channel == MEM_FG_SYNC))
+           (channel == MEM_FG_SYNC)) {
+               reg = __raw_readl(IDMAC_WM_EN(in_dma));
+               __raw_writel(reg | idma_mask(in_dma), IDMAC_WM_EN(in_dma));
+
                ipu_dp_dc_enable(channel);
+       }
 
        g_channel_enable_mask |= 1L << IPU_CHAN_ID(channel);
 
@@ -1141,32 +1118,27 @@ int32_t ipu_disable_channel(ipu_channel_t channel)
 uint32_t bytes_per_pixel(uint32_t fmt)
 {
        switch (fmt) {
-       case IPU_PIX_FMT_GENERIC:       /*generic data */
+       case IPU_PIX_FMT_GENERIC:       /* generic data */
        case IPU_PIX_FMT_RGB332:
        case IPU_PIX_FMT_YUV420P:
        case IPU_PIX_FMT_YUV422P:
                return 1;
-               break;
        case IPU_PIX_FMT_RGB565:
        case IPU_PIX_FMT_YUYV:
        case IPU_PIX_FMT_UYVY:
                return 2;
-               break;
        case IPU_PIX_FMT_BGR24:
        case IPU_PIX_FMT_RGB24:
                return 3;
-               break;
-       case IPU_PIX_FMT_GENERIC_32:    /*generic data */
+       case IPU_PIX_FMT_GENERIC_32:    /* generic data */
        case IPU_PIX_FMT_BGR32:
        case IPU_PIX_FMT_BGRA32:
        case IPU_PIX_FMT_RGB32:
        case IPU_PIX_FMT_RGBA32:
        case IPU_PIX_FMT_ABGR32:
                return 4;
-               break;
        default:
                return 1;
-               break;
        }
        return 0;
 }
@@ -1186,11 +1158,9 @@ ipu_color_space_t format_to_colorspace(uint32_t fmt)
        case IPU_PIX_FMT_LVDS666:
        case IPU_PIX_FMT_LVDS888:
                return RGB;
-               break;
 
        default:
                return YCbCr;
-               break;
        }
        return RGB;
 }
index 4faeafb6351d4d3e75376e704b479ebad4a3c6b3..b5490b7980277c8097f7073094907609fd979c06 100644 (file)
@@ -4,9 +4,9 @@
  * (C) Copyright 2010
  * Stefano Babic, DENX Software Engineering, sbabic@denx.de
  *
- * Linux IPU driver for MX51:
+ * Linux IPU driver
  *
- * (C) Copyright 2005-2010 Freescale Semiconductor, Inc.
+ * (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 /* #define DEBUG */
 
 #include <common.h>
+#include <ipu.h>
 #include <linux/types.h>
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/sys_proto.h>
-#include "ipu.h"
 #include "ipu_regs.h"
 
 enum csc_type_t {
@@ -43,17 +43,9 @@ struct dp_csc_param_t {
 #define DC_DISP_ID_SERIAL      2
 #define DC_DISP_ID_ASYNC       3
 
-int dmfc_type_setup;
+static int dmfc_type_setup;
 static int dmfc_size_28, dmfc_size_29, dmfc_size_24, dmfc_size_27, dmfc_size_23;
-int g_di1_tvout;
-
-extern struct clk *g_ipu_clk;
-extern struct clk *g_ldb_clk;
-extern struct clk *g_di_clk[2];
-extern struct clk *g_pixel_clk[2];
-
-extern unsigned char g_ipu_clk_enabled;
-extern unsigned char g_dc_di_assignment[];
+static int g_di1_tvout;
 
 void ipu_dmfc_init(int dmfc_type, int first)
 {
@@ -767,8 +759,8 @@ void ipu_init_dc_mappings(void)
        /* IPU_PIX_FMT_LVDS666 */
        ipu_dc_map_clear(4);
        ipu_dc_map_config(4, 0, 5, 0xFC);
-       ipu_dc_map_config(4, 1, 13, 0xFC);
-       ipu_dc_map_config(4, 2, 21, 0xFC);
+       ipu_dc_map_config(4, 1, 11, 0xFC);
+       ipu_dc_map_config(4, 2, 17, 0xFC);
 }
 
 static int ipu_pixfmt_to_map(uint32_t fmt)
@@ -776,6 +768,7 @@ static int ipu_pixfmt_to_map(uint32_t fmt)
        switch (fmt) {
        case IPU_PIX_FMT_GENERIC:
        case IPU_PIX_FMT_RGB24:
+       case IPU_PIX_FMT_LVDS888:
                return 0;
        case IPU_PIX_FMT_RGB666:
                return 1;
@@ -787,7 +780,7 @@ static int ipu_pixfmt_to_map(uint32_t fmt)
                return 4;
        }
 
-       return -1;
+       return -EINVAL;
 }
 
 /*
@@ -827,13 +820,13 @@ static int ipu_pixfmt_to_map(uint32_t fmt)
  *              fail.
  */
 
-int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
-                           uint16_t width, uint16_t height,
-                           uint32_t pixel_fmt,
-                           uint16_t h_start_width, uint16_t h_sync_width,
-                           uint16_t h_end_width, uint16_t v_start_width,
-                           uint16_t v_sync_width, uint16_t v_end_width,
-                           uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
+int ipu_init_sync_panel(int disp, uint32_t pixel_clk,
+                       uint16_t width, uint16_t height,
+                       uint32_t pixel_fmt,
+                       uint16_t h_start_width, uint16_t h_sync_width,
+                       uint16_t h_end_width, uint16_t v_start_width,
+                       uint16_t v_sync_width, uint16_t v_end_width,
+                       uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig)
 {
        uint32_t reg;
        uint32_t di_gen, vsync_cnt;
@@ -860,7 +853,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
        debug("pixel clk = %dHz\n", pixel_clk);
 
        if (sig.ext_clk) {
-               if (!(g_di1_tvout && (disp == 1))) { /*not round div for tvout*/
+               if (!(g_di1_tvout && (disp == 1))) { /* don't round div for tvout */
                        /*
                         * Set the  PLL to be an even multiple
                         * of the pixel clock.
@@ -871,18 +864,20 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
                                rounded_pixel_clk =
                                        clk_round_rate(g_pixel_clk[disp],
                                                pixel_clk);
-                               div  = clk_get_rate(di_parent) /
-                                       rounded_pixel_clk;
-                               if (div % 2)
-                                       div++;
-                               if (clk_get_rate(di_parent) != div *
-                                       rounded_pixel_clk)
-                                       clk_set_rate(di_parent,
-                                               div * rounded_pixel_clk);
-                               udelay(10000);
-                               clk_set_rate(g_di_clk[disp],
-                                       2 * rounded_pixel_clk);
-                               udelay(10000);
+                               if (di_parent != NULL) {
+                                       div  = clk_get_rate(di_parent) /
+                                               rounded_pixel_clk;
+                                       if (div % 2)
+                                               div++;
+                                       if (clk_get_rate(di_parent) != div *
+                                               rounded_pixel_clk)
+                                               clk_set_rate(di_parent,
+                                                       div * rounded_pixel_clk);
+                                       udelay(10000);
+                                       clk_set_rate(g_di_clk[disp],
+                                               2 * rounded_pixel_clk);
+                                       udelay(10000);
+                               }
                        }
                }
                clk_set_parent(g_pixel_clk[disp], g_ldb_clk);
@@ -890,24 +885,44 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
                if (clk_get_usecount(g_pixel_clk[disp]) != 0)
                        clk_set_parent(g_pixel_clk[disp], g_ipu_clk);
        }
-       rounded_pixel_clk = clk_round_rate(g_pixel_clk[disp], pixel_clk);
-       clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk);
-       udelay(5000);
-       /* Get integer portion of divider */
-       div = clk_get_rate(clk_get_parent(g_pixel_clk[disp])) /
-               rounded_pixel_clk;
-
-       ipu_di_data_wave_config(disp, SYNC_WAVE, div - 1, div - 1);
+
+       /* Enable for a divide by 2 clock change. */
+       reg = __raw_readl(IPU_PM);
+       reg &= ~(0x7f << 7);
+       reg |= 0x20 << 7;
+       reg &= ~(0x7f << 23);
+       reg |= 0x20 << 23;
+       __raw_writel(reg, IPU_PM);
+
+       di_gen = 0;
+
+       if (pixel_fmt != IPU_PIX_FMT_LVDS666 &&
+                       pixel_fmt != IPU_PIX_FMT_LVDS888) {
+               rounded_pixel_clk = clk_round_rate(g_pixel_clk[disp], pixel_clk);
+               clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk);
+               udelay(5000);
+               /* Get integer portion of divider */
+               div = clk_get_rate(clk_get_parent(g_pixel_clk[disp])) /
+                       rounded_pixel_clk;
+               ipu_di_data_wave_config(disp, SYNC_WAVE, div - 1, div - 1);
+       } else {
+               rounded_pixel_clk = clk_get_rate(clk_get_parent(g_pixel_clk[disp]));
+               clk_set_rate(g_pixel_clk[disp], rounded_pixel_clk);
+               div = 1;
+               ipu_di_data_wave_config(disp, SYNC_WAVE, 0, 0);
+               di_gen |= (6 << 24);
+               di_gen |= DI_GEN_DI_CLK_EXT;
+       }
        ipu_di_data_pin_config(disp, SYNC_WAVE, DI_PIN15, 3, 0, div * 2);
 
        map = ipu_pixfmt_to_map(pixel_fmt);
        if (map < 0) {
-               debug("IPU_DISP: No MAP\n");
-               return -EINVAL;
+               printf("IPU_DISP: No MAP for pixel format: %c%c%c%c\n",
+                       pixel_fmt, pixel_fmt >> 8, pixel_fmt >> 16,
+                       pixel_fmt >> 24);
+               return map;
        }
 
-       di_gen = __raw_readl(DI_GENERAL(disp));
-
        if (sig.interlaced) {
                /* Setup internal HSYNC waveform */
                ipu_di_sync_config(
@@ -1065,7 +1080,7 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
                /* set gentime select and tag sel */
                reg = __raw_readl(DI_SW_GEN1(disp, 9));
                reg &= 0x1FFFFFFF;
-               reg |= (3 - 1)<<29 | 0x00008000;
+               reg |= ((3 - 1) << 29) | 0x00008000;
                __raw_writel(reg, DI_SW_GEN1(disp, 9));
 
                __raw_writel(v_total / 2 - 1, DI_SCR_CONF(disp));
@@ -1121,15 +1136,20 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
                __raw_writel(0, DI_STP_REP(disp, 7));
                __raw_writel(0, DI_STP_REP(disp, 9));
 
+               h_total = ((width + h_start_width + h_sync_width) / 2) - 2;
+               ipu_di_sync_config(disp, 6, 1, 0, 2, DI_SYNC_CLK, h_total,
+                               DI_SYNC_INT_HSYNC, 0, DI_SYNC_NONE,
+                               DI_SYNC_NONE, 0, 0);
+
                /* Init template microcode */
                if (disp) {
-                  ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5);
-                  ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5);
-                  ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+                       ipu_dc_write_tmpl(2, WROD(0), 0, map, SYNC_WAVE, 8, 5);
+                       ipu_dc_write_tmpl(3, WROD(0), 0, map, SYNC_WAVE, 4, 5);
+                       ipu_dc_write_tmpl(4, WROD(0), 0, map, SYNC_WAVE, 0, 5);
                } else {
-                  ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5);
-                  ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5);
-                  ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5);
+                       ipu_dc_write_tmpl(5, WROD(0), 0, map, SYNC_WAVE, 8, 5);
+                       ipu_dc_write_tmpl(6, WROD(0), 0, map, SYNC_WAVE, 4, 5);
+                       ipu_dc_write_tmpl(7, WROD(0), 0, map, SYNC_WAVE, 0, 5);
                }
 
                if (sig.Hsync_pol)
@@ -1140,12 +1160,18 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
                if (!sig.clk_pol)
                        di_gen |= DI_GEN_POL_CLK;
 
+               /* Set the clock to stop at counter 6. */
+               di_gen |= 0x6000000;
        }
 
        __raw_writel(di_gen, DI_GENERAL(disp));
 
-       __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
-                       0x00000002, DI_SYNC_AS_GEN(disp));
+       if (sig.interlaced)
+               __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET) |
+                               0x00000002, DI_SYNC_AS_GEN(disp));
+       else
+               __raw_writel((--vsync_cnt << DI_VSYNC_SEL_OFFSET),
+                               DI_SYNC_AS_GEN(disp));
 
        reg = __raw_readl(DI_POL(disp));
        reg &= ~(DI_POL_DRDY_DATA_POLARITY | DI_POL_DRDY_POLARITY_15);
@@ -1174,9 +1200,10 @@ int32_t ipu_init_sync_panel(int disp, uint32_t pixel_clk,
  *
  * @return      Returns 0 on success or negative error code on fail
  */
-int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
+int ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
                                  uint8_t alpha)
 {
+       int ret;
        uint32_t reg;
 
        unsigned char bg_chan;
@@ -1192,8 +1219,9 @@ int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
        else
                bg_chan = 0;
 
-       if (!g_ipu_clk_enabled)
-               clk_enable(g_ipu_clk);
+       ret = clk_enable(g_ipu_clk);
+       if (ret)
+               return ret;
 
        if (bg_chan) {
                reg = __raw_readl(DP_COM_CONF());
@@ -1218,8 +1246,7 @@ int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
        reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
        __raw_writel(reg, IPU_SRM_PRI2);
 
-       if (!g_ipu_clk_enabled)
-               clk_disable(g_ipu_clk);
+       clk_disable(g_ipu_clk);
 
        return 0;
 }
@@ -1235,9 +1262,10 @@ int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
  *
  * @return      Returns 0 on success or negative error code on fail
  */
-int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
+int ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
                               uint32_t color_key)
 {
+       int ret;
        uint32_t reg;
        int y, u, v;
        int red, green, blue;
@@ -1247,8 +1275,9 @@ int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
                (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1)))
                return -EINVAL;
 
-       if (!g_ipu_clk_enabled)
-               clk_enable(g_ipu_clk);
+       ret = clk_enable(g_ipu_clk);
+       if (ret)
+               return ret;
 
        color_key_4rgb = 1;
        /* Transform color key from rgb to yuv if CSC is enabled */
@@ -1287,8 +1316,7 @@ int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
        reg = __raw_readl(IPU_SRM_PRI2) | 0x8;
        __raw_writel(reg, IPU_SRM_PRI2);
 
-       if (!g_ipu_clk_enabled)
-               clk_disable(g_ipu_clk);
+       clk_disable(g_ipu_clk);
 
        return 0;
 }
index c2c134a7de0738beca41c7b871c0869d5f6fe031..ea0cf4141bd1eb265594ffba13cd6f3a36dd511b 100644 (file)
@@ -4,9 +4,9 @@
  * (C) Copyright 2010
  * Stefano Babic, DENX Software Engineering, sbabic@denx.de
  *
- * Linux IPU driver for MX51:
+ * Linux IPU driver:
  *
- * (C) Copyright 2005-2009 Freescale Semiconductor, Inc.
+ * (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 #ifndef __IPU_REGS_INCLUDED__
 #define __IPU_REGS_INCLUDED__
 
+#include <asm/arch/imx-regs.h>
+
 #define IPU_DISP0_BASE         0x00000000
 #define IPU_MCU_T_DEFAULT      8
-#define IPU_DISP1_BASE         (IPU_MCU_T_DEFAULT << 25)
+#define IPU_DISP1_BASE         (gd->arch.ipu_hw_rev < IPUV3_HW_REV_IPUV3H ?    \
+                               (IPU_MCU_T_DEFAULT << 25) :             \
+                               0x00000000)
+
+#define IPUV3DEX_REG_BASE      0x1E000000
+#define IPUV3M_REG_BASE                0x1E000000
+#define IPUV3H_REG_BASE                0x00200000
+
 #define IPU_CM_REG_BASE                0x00000000
 #define IPU_STAT_REG_BASE      0x00000200
 #define IPU_IDMAC_REG_BASE     0x00008000
 #define IPU_SMFC_REG_BASE      0x00050000
 #define IPU_DC_REG_BASE                0x00058000
 #define IPU_DMFC_REG_BASE      0x00060000
-#define IPU_VDI_REG_BASE       0x00680000
-#if defined(CONFIG_MX51) || defined(CONFIG_MX53)
-#define IPU_CPMEM_REG_BASE     0x01000000
-#define IPU_LUT_REG_BASE       0x01020000
-#define IPU_SRM_REG_BASE       0x01040000
-#define IPU_TPM_REG_BASE       0x01060000
-#define IPU_DC_TMPL_REG_BASE   0x01080000
-#define IPU_ISP_TBPR_REG_BASE  0x010C0000
-#elif defined(CONFIG_MX6)
-#define IPU_CPMEM_REG_BASE     0x00100000
-#define IPU_LUT_REG_BASE       0x00120000
-#define IPU_SRM_REG_BASE       0x00140000
-#define IPU_TPM_REG_BASE       0x00160000
-#define IPU_DC_TMPL_REG_BASE   0x00180000
-#define IPU_ISP_TBPR_REG_BASE  0x001C0000
-#endif
-
-#define IPU_CTRL_BASE_ADDR     (IPU_SOC_BASE_ADDR + IPU_SOC_OFFSET)
+#define IPU_VDI_REG_BASE       0x00068000
+#define IPU_CPMEM_REG_BASE     (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00100000 :                            \
+                               0x01000000)
+#define IPU_LUT_REG_BASE       (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00120000 :                            \
+                               0x01020000)
+#define IPU_SRM_REG_BASE       (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00140000 :                            \
+                               0x01040000)
+#define IPU_TPM_REG_BASE       (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00160000 :                            \
+                               0x01060000)
+#define IPU_DC_TMPL_REG_BASE   (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x00180000 :                            \
+                               0x01080000)
+#define IPU_ISP_TBPR_REG_BASE  (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               0x001C0000 :                            \
+                               0x010C0000)
+
+#define IPU_DISP_REG_BASE_ADDR (gd->arch.ipu_hw_rev >= IPUV3_HW_REV_IPUV3H ?   \
+                               IPU_SOC_BASE_ADDR + IPUV3H_REG_BASE :   \
+                               IPU_SOC_BASE_ADDR + IPUV3M_REG_BASE)
 
 extern u32 *ipu_dc_tmpl_reg;
+extern struct clk *g_ipu_clk;
+extern struct clk *g_ldb_clk;
+extern struct clk *g_di_clk[2];
+extern struct clk *g_pixel_clk[2];
+
+extern int g_ipu_clk_enabled;
+extern unsigned char g_dc_di_assignment[];
 
 #define DC_EVT_NF              0
 #define DC_EVT_NL              1
@@ -91,7 +112,7 @@ enum {
        DI_DW_GEN_ACCESS_SIZE_OFFSET = 24,
        DI_DW_GEN_COMPONENT_SIZE_OFFSET = 16,
 
-       DI_GEN_DI_CLK_EXT = 0x100000,
+       DI_GEN_DI_CLK_EXT = 0x00100000,
        DI_GEN_POLARITY_1 = 0x00000001,
        DI_GEN_POLARITY_2 = 0x00000002,
        DI_GEN_POLARITY_3 = 0x00000004,
@@ -100,7 +121,7 @@ enum {
        DI_GEN_POLARITY_6 = 0x00000020,
        DI_GEN_POLARITY_7 = 0x00000040,
        DI_GEN_POLARITY_8 = 0x00000080,
-       DI_GEN_POL_CLK = 0x20000,
+       DI_GEN_POL_CLK    = 0x00020000,
 
        DI_POL_DRDY_DATA_POLARITY = 0x00000080,
        DI_POL_DRDY_POLARITY_15 = 0x00000010,
@@ -297,7 +318,7 @@ struct ipu_dmfc {
        u32 stat;
 };
 
-#define IPU_CM_REG             ((struct ipu_cm *)(IPU_CTRL_BASE_ADDR + \
+#define IPU_CM_REG             ((struct ipu_cm *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_CM_REG_BASE))
 #define IPU_CONF               (&IPU_CM_REG->conf)
 #define IPU_SRM_PRI1           (&IPU_CM_REG->srm_pri1)
@@ -308,43 +329,46 @@ struct ipu_dmfc {
 #define IPU_FS_DISP_FLOW1      (&IPU_CM_REG->fs_disp_flow[0])
 #define IPU_DISP_GEN           (&IPU_CM_REG->disp_gen)
 #define IPU_MEM_RST            (&IPU_CM_REG->mem_rst)
+#define IPU_PM                 (&IPU_CM_REG->pm)
 #define IPU_GPR                        (&IPU_CM_REG->gpr)
-#define IPU_CHA_DB_MODE_SEL(ch)        (&IPU_CM_REG->ch_db_mode_sel[ch / 32])
+#define IPU_CHA_DB_MODE_SEL(ch)        (&IPU_CM_REG->ch_db_mode_sel[(ch) / 32])
 
-#define IPU_STAT               ((struct ipu_stat *)(IPU_CTRL_BASE_ADDR + \
+#define IPU_STAT               ((struct ipu_stat *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_STAT_REG_BASE))
 #define IPU_INT_STAT(n)                (&IPU_STAT->int_stat[(n) - 1])
-#define IPU_CHA_CUR_BUF(ch)    (&IPU_STAT->cur_buf[ch / 32])
-#define IPU_CHA_BUF0_RDY(ch)   (&IPU_STAT->ch_buf0_rdy[ch / 32])
-#define IPU_CHA_BUF1_RDY(ch)   (&IPU_STAT->ch_buf1_rdy[ch / 32])
+#define IPU_CHA_CUR_BUF(ch)    (&IPU_STAT->cur_buf[(ch) / 32])
+#define IPU_CHA_BUF0_RDY(ch)   (&IPU_STAT->ch_buf0_rdy[(ch) / 32])
+#define IPU_CHA_BUF1_RDY(ch)   (&IPU_STAT->ch_buf1_rdy[(ch) / 32])
 #define IPUIRQ_2_STATREG(irq)  (IPU_INT_STAT(1) + ((irq) / 32))
 #define IPUIRQ_2_MASK(irq)     (1UL << ((irq) & 0x1F))
 
 #define IPU_INT_CTRL(n)                (&IPU_CM_REG->int_ctrl[(n) - 1])
 
-#define IDMAC_REG              ((struct ipu_idmac *)(IPU_CTRL_BASE_ADDR + \
+#define IDMAC_REG              ((struct ipu_idmac *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_IDMAC_REG_BASE))
 #define IDMAC_CONF             (&IDMAC_REG->conf)
-#define IDMAC_CHA_EN(ch)       (&IDMAC_REG->ch_en[ch / 32])
-#define IDMAC_CHA_PRI(ch)      (&IDMAC_REG->ch_pri[ch / 32])
+#define IDMAC_CHA_EN(ch)       (&IDMAC_REG->ch_en[(ch) / 32])
+#define IDMAC_CHA_PRI(ch)      (&IDMAC_REG->ch_pri[(ch) / 32])
+#define IDMAC_WM_EN(ch)                (&IDMAC_REG->wm_en[(ch) / 32])
+
+#define DI_REG(di)             ((struct ipu_di *)(IPU_DISP_REG_BASE_ADDR + \
+                                       (((di) == 1) ? IPU_DI1_REG_BASE : \
+                                       IPU_DI0_REG_BASE)))
 
-#define DI_REG(di)             ((struct ipu_di *)(IPU_CTRL_BASE_ADDR + \
-                               ((di == 1) ? IPU_DI1_REG_BASE : \
-                               IPU_DI0_REG_BASE)))
 #define DI_GENERAL(di)         (&DI_REG(di)->general)
 #define DI_BS_CLKGEN0(di)      (&DI_REG(di)->bs_clkgen0)
 #define DI_BS_CLKGEN1(di)      (&DI_REG(di)->bs_clkgen1)
 
-#define DI_SW_GEN0(di, gen)    (&DI_REG(di)->sw_gen0[gen - 1])
-#define DI_SW_GEN1(di, gen)    (&DI_REG(di)->sw_gen1[gen - 1])
-#define DI_STP_REP(di, gen)    (&DI_REG(di)->stp_rep[(gen - 1) / 2])
+#define DI_SW_GEN0(di, gen)    (&DI_REG(di)->sw_gen0[(gen) - 1])
+#define DI_SW_GEN1(di, gen)    (&DI_REG(di)->sw_gen1[(gen) - 1])
+#define DI_STP_REP(di, gen)    (&DI_REG(di)->stp_rep[((gen) - 1) / 2])
 #define DI_SYNC_AS_GEN(di)     (&DI_REG(di)->sync_as)
 #define DI_DW_GEN(di, gen)     (&DI_REG(di)->dw_gen[gen])
-#define DI_DW_SET(di, gen, set)        (&DI_REG(di)->dw_set[gen + 12 * set])
+#define DI_DW_SET(di, gen, set)        (&DI_REG(di)->dw_set[(gen) + 12 * set])
 #define DI_POL(di)             (&DI_REG(di)->pol)
 #define DI_SCR_CONF(di)                (&DI_REG(di)->scr_conf)
 
-#define DMFC_REG               ((struct ipu_dmfc *)(IPU_CTRL_BASE_ADDR + \
+#define DMFC_REG               ((struct ipu_dmfc *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_DMFC_REG_BASE))
 #define DMFC_WR_CHAN           (&DMFC_REG->wr_chan)
 #define DMFC_WR_CHAN_DEF       (&DMFC_REG->wr_chan_def)
@@ -353,12 +377,12 @@ struct ipu_dmfc {
 #define DMFC_GENERAL1          (&DMFC_REG->general[0])
 #define DMFC_IC_CTRL           (&DMFC_REG->ic_ctrl)
 
-
-#define DC_REG                 ((struct ipu_dc *)(IPU_CTRL_BASE_ADDR + \
+#define DC_REG                 ((struct ipu_dc *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_DC_REG_BASE))
-#define DC_MAP_CONF_PTR(n)     (&DC_REG->dc_map_ptr[n / 2])
-#define DC_MAP_CONF_VAL(n)     (&DC_REG->dc_map_val[n / 2])
+#define DC_MAP_CONF_PTR(n)     (&DC_REG->dc_map_ptr[(n) / 2])
+#define DC_MAP_CONF_VAL(n)     (&DC_REG->dc_map_val[(n) / 2])
 
+DECLARE_GLOBAL_DATA_PTR;
 
 static inline struct ipu_dc_ch *dc_ch_offset(int ch)
 {
@@ -378,10 +402,9 @@ static inline struct ipu_dc_ch *dc_ch_offset(int ch)
                printf("%s: invalid channel %d\n", __func__, ch);
                return NULL;
        }
-
 }
 
-#define DC_RL_CH(ch, evt)      (&dc_ch_offset(ch)->rl[evt / 2])
+#define DC_RL_CH(ch, evt)      (&dc_ch_offset(ch)->rl[(evt) / 2])
 
 #define DC_WR_CH_CONF(ch)      (&dc_ch_offset(ch)->wr_ch_conf)
 #define DC_WR_CH_ADDR(ch)      (&dc_ch_offset(ch)->wr_ch_addr)
@@ -397,7 +420,7 @@ static inline struct ipu_dc_ch *dc_ch_offset(int ch)
 #define DP_ASYNC0 0x60
 #define DP_ASYNC1 0xBC
 
-#define DP_REG                 ((struct ipu_dp *)(IPU_CTRL_BASE_ADDR + \
+#define DP_REG                 ((struct ipu_dp *)(IPU_DISP_REG_BASE_ADDR + \
                                IPU_DP_REG_BASE))
 #define DP_COM_CONF()          (&DP_REG->com_conf_sync)
 #define DP_GRAPH_WIND_CTRL()   (&DP_REG->graph_wind_ctrl_sync)
@@ -410,6 +433,6 @@ static inline struct ipu_dc_ch *dc_ch_offset(int ch)
 #define DP_CSC_1()             (&DP_REG->csc_sync[1])
 
 /* DC template opcodes */
-#define WROD(lf)               (0x18 | (lf << 1))
+#define WROD(lf)               (0x18 | ((lf) << 1))
 
 #endif
index 1fa95314fc4621857114bcef2e98e50a60f163b7..cd95abab837064a5616649a6b85c4e255062a27b 100644 (file)
@@ -4,13 +4,14 @@
  * (C) Copyright 2010
  * Stefano Babic, DENX Software Engineering, sbabic@denx.de
  *
- * MX51 Linux framebuffer:
+ * IPUv3 Linux framebuffer:
  *
- * (C) Copyright 2004-2010 Freescale Semiconductor, Inc.
+ * (C) Copyright 2004-2011 Freescale Semiconductor, Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+/* #define DEBUG */
 #include <common.h>
 #include <asm/errno.h>
 #include <asm/global_data.h>
 #include <linux/fb.h>
 #include <asm/io.h>
 #include <malloc.h>
+#include <lcd.h>
+#include <ipu.h>
 #include <video_fb.h>
-#include "videomodes.h"
-#include "ipu.h"
-#include "mxcfb.h"
+#include <mxcfb.h>
+
 #include "ipu_regs.h"
+#include "videomodes.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
 static int mxcfb_map_video_memory(struct fb_info *fbi);
 static int mxcfb_unmap_video_memory(struct fb_info *fbi);
 
-/* graphics setup */
-static GraphicDevice panel;
-static struct fb_videomode const *gmode;
-static uint8_t gdisp;
-static uint32_t gpixfmt;
+void lcd_initcolregs(void)
+{
+}
+
+void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
+{
+}
 
 static void fb_videomode_to_var(struct fb_var_screeninfo *var,
                         const struct fb_videomode *mode)
@@ -108,6 +113,8 @@ static uint32_t bpp_to_pixfmt(struct fb_info *fbi)
        case 16:
                pixfmt = IPU_PIX_FMT_RGB565;
                break;
+       case 8:
+               pixfmt = IPU_PIX_FMT_GENERIC;
        }
        return pixfmt;
 }
@@ -136,7 +143,7 @@ static int mxcfb_set_fix(struct fb_info *info)
 static int setup_disp_channel1(struct fb_info *fbi)
 {
        ipu_channel_params_t params;
-       struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+       struct mxcfb_info *mxc_fbi = fbi->par;
 
        memset(&params, 0, sizeof(params));
        params.mem_dp_bg_sync.di = mxc_fbi->ipu_di;
@@ -171,7 +178,7 @@ static int setup_disp_channel1(struct fb_info *fbi)
 static int setup_disp_channel2(struct fb_info *fbi)
 {
        int retval = 0;
-       struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+       struct mxcfb_info *mxc_fbi = fbi->par;
 
        mxc_fbi->cur_ipu_buf = 1;
        if (mxc_fbi->alpha_chan_en)
@@ -179,7 +186,7 @@ static int setup_disp_channel2(struct fb_info *fbi)
 
        fbi->var.xoffset = fbi->var.yoffset = 0;
 
-       debug("%s: %x %d %d %d %lx %lx\n",
+       debug("%s: ch: %08x xres: %d yres: %d line_length: %d mem: %08lx .. %08lx\n",
                __func__,
                mxc_fbi->ipu_ch,
                fbi->var.xres,
@@ -187,7 +194,7 @@ static int setup_disp_channel2(struct fb_info *fbi)
                fbi->fix.line_length,
                fbi->fix.smem_start,
                fbi->fix.smem_start +
-               (fbi->fix.line_length * fbi->var.yres));
+               (fbi->fix.line_length * fbi->var.yres) - 1);
 
        retval = ipu_init_channel_buffer(mxc_fbi->ipu_ch, IPU_INPUT_BUFFER,
                                         bpp_to_pixfmt(fbi),
@@ -213,7 +220,7 @@ static int mxcfb_set_par(struct fb_info *fbi)
        int retval = 0;
        u32 mem_len;
        ipu_di_signal_cfg_t sig_cfg;
-       struct mxcfb_info *mxc_fbi = (struct mxcfb_info *)fbi->par;
+       struct mxcfb_info *mxc_fbi = fbi->par;
        uint32_t out_pixel_fmt;
 
        ipu_disable_channel(mxc_fbi->ipu_ch);
@@ -258,9 +265,11 @@ static int mxcfb_set_par(struct fb_info *fbi)
        if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN)
                sig_cfg.clkidle_en = 1;
 
-       debug("pixclock = %lu Hz\n", PICOS2KHZ(fbi->var.pixclock) * 1000UL);
+       debug("pixclock = %lu.%03lu MHz\n",
+               PICOS2KHZ(fbi->var.pixclock) / 1000,
+               PICOS2KHZ(fbi->var.pixclock) % 1000);
 
-       if (ipu_init_sync_panel(mxc_fbi->ipu_di,
+       retval = ipu_init_sync_panel(mxc_fbi->ipu_di,
                                (PICOS2KHZ(fbi->var.pixclock)) * 1000UL,
                                fbi->var.xres, fbi->var.yres,
                                out_pixel_fmt,
@@ -270,9 +279,10 @@ static int mxcfb_set_par(struct fb_info *fbi)
                                fbi->var.upper_margin,
                                fbi->var.vsync_len,
                                fbi->var.lower_margin,
-                               0, sig_cfg) != 0) {
-               puts("mxcfb: Error initializing panel.\n");
-               return -EINVAL;
+                               0, sig_cfg);
+       if (retval != 0) {
+               printf("mxc_ipuv3_fb: Error %d initializing panel\n", retval);
+               return retval;
        }
 
        retval = setup_disp_channel2(fbi);
@@ -401,16 +411,19 @@ static int mxcfb_map_video_memory(struct fb_info *fbi)
                fbi->fix.smem_len = fbi->var.yres_virtual *
                                    fbi->fix.line_length;
        }
+
        fbi->fix.smem_len = roundup(fbi->fix.smem_len, ARCH_DMA_MINALIGN);
-       fbi->screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
-                                           fbi->fix.smem_len);
-       fbi->fix.smem_start = (unsigned long)fbi->screen_base;
-       if (fbi->screen_base == 0) {
+       if (gd->fb_base)
+               fbi->screen_base = (void *)gd->fb_base;
+       else
+               fbi->screen_base = (char *)memalign(ARCH_DMA_MINALIGN,
+                                               fbi->fix.smem_len);
+       if (fbi->screen_base == NULL) {
                puts("Unable to allocate framebuffer memory\n");
                fbi->fix.smem_len = 0;
-               fbi->fix.smem_start = 0;
                return -EBUSY;
        }
+       fbi->fix.smem_start = (unsigned long)fbi->screen_base;
 
        debug("allocated fb @ paddr=0x%08X, size=%d.\n",
                (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len);
@@ -419,9 +432,6 @@ static int mxcfb_map_video_memory(struct fb_info *fbi)
 
        gd->fb_base = fbi->fix.smem_start;
 
-       /* Clear the screen */
-       memset((char *)fbi->screen_base, 0, fbi->fix.smem_len);
-
        return 0;
 }
 
@@ -444,17 +454,14 @@ static int mxcfb_unmap_video_memory(struct fb_info *fbi)
  */
 static struct fb_info *mxcfb_init_fbinfo(void)
 {
-#define BYTES_PER_LONG 4
-#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
        struct fb_info *fbi;
        struct mxcfb_info *mxcfbi;
-       char *p;
-       int size = sizeof(struct mxcfb_info) + PADDING +
+       void *p;
+       int size = ALIGN(sizeof(struct mxcfb_info), sizeof(long)) +
                sizeof(struct fb_info);
 
-       debug("%s: %d %d %d %d\n",
+       debug("%s: %d %d %d\n",
                __func__,
-               PADDING,
                size,
                sizeof(struct mxcfb_info),
                sizeof(struct fb_info));
@@ -468,12 +475,12 @@ static struct fb_info *mxcfb_init_fbinfo(void)
 
        memset(p, 0, size);
 
-       fbi = (struct fb_info *)p;
-       fbi->par = p + sizeof(struct fb_info) + PADDING;
+       fbi = p;
+       fbi->par = p + ALIGN(sizeof(struct fb_info), sizeof(long));
 
-       mxcfbi = (struct mxcfb_info *)fbi->par;
-       debug("Framebuffer structures at: fbi=0x%x mxcfbi=0x%x\n",
-               (unsigned int)fbi, (unsigned int)mxcfbi);
+       mxcfbi = fbi->par;
+       debug("Framebuffer structures at: fbi=%p mxcfbi=%p\n",
+               fbi, mxcfbi);
 
        fbi->var.activate = FB_ACTIVATE_NOW;
 
@@ -491,22 +498,19 @@ static struct fb_info *mxcfb_init_fbinfo(void)
  *
  * @return      Appropriate error code to the kernel common code
  */
-static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
-                       struct fb_videomode const *mode)
+static int mxcfb_probe(u32 interface_pix_fmt, struct fb_videomode *mode, int di)
 {
        struct fb_info *fbi;
        struct mxcfb_info *mxcfbi;
-       int ret = 0;
 
        /*
         * Initialize FB structures
         */
        fbi = mxcfb_init_fbinfo();
-       if (!fbi) {
-               ret = -ENOMEM;
-               goto err0;
-       }
-       mxcfbi = (struct mxcfb_info *)fbi->par;
+       if (!fbi)
+               return -ENOMEM;
+
+       mxcfbi = fbi->par;
 
        if (!g_dp_in_use) {
                mxcfbi->ipu_ch = MEM_BG_SYNC;
@@ -516,7 +520,7 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
                mxcfbi->blank = FB_BLANK_POWERDOWN;
        }
 
-       mxcfbi->ipu_di = disp;
+       mxcfbi->ipu_di = di;
 
        ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80);
        ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0);
@@ -527,10 +531,12 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
        mxcfb_info[mxcfbi->ipu_di] = fbi;
 
        /* Need dummy values until real panel is configured */
+       fbi->var.xres = panel_info.vl_col;
+       fbi->var.yres = panel_info.vl_row;
 
        mxcfbi->ipu_di_pix_fmt = interface_pix_fmt;
        fb_videomode_to_var(&fbi->var, mode);
-       fbi->var.bits_per_pixel = 16;
+       fbi->var.bits_per_pixel = NBITS(panel_info.vl_bpix);
        fbi->fix.line_length = fbi->var.xres * (fbi->var.bits_per_pixel / 8);
        fbi->fix.smem_len = fbi->var.yres_virtual * fbi->fix.line_length;
 
@@ -547,23 +553,23 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp,
 
        mxcfb_set_par(fbi);
 
-       panel.winSizeX = mode->xres;
-       panel.winSizeY = mode->yres;
-       panel.plnSizeX = mode->xres;
-       panel.plnSizeY = mode->yres;
+       lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
 
-       panel.frameAdrs = (u32)fbi->screen_base;
-       panel.memSize = fbi->screen_size;
-
-       panel.gdfBytesPP = 2;
-       panel.gdfIndex = GDF_16BIT_565RGB;
+       debug("MXC IPUV3 configured\n"
+               "XRES = %d YRES = %d BitsXpixel = %d\n",
+               panel_info.vl_col,
+               panel_info.vl_row,
+               panel_info.vl_bpix);
 
        ipu_dump_registers();
 
        return 0;
+}
 
-err0:
-       return ret;
+ulong calc_fbsize(void)
+{
+       return (panel_info.vl_col * panel_info.vl_row *
+               NBITS(panel_info.vl_bpix)) / 8;
 }
 
 void ipuv3_fb_shutdown(void)
@@ -579,42 +585,26 @@ void ipuv3_fb_shutdown(void)
                        ipu_uninit_channel(mxc_fbi->ipu_ch);
                }
        }
+       clk_enable(g_ipu_clk);
        for (i = 0; i < ARRAY_SIZE(stat->int_stat); i++) {
                __raw_writel(__raw_readl(&stat->int_stat[i]),
                             &stat->int_stat[i]);
        }
+       clk_disable(g_ipu_clk);
 }
 
-void *video_hw_init(void)
+int ipuv3_fb_init(struct fb_videomode *mode, int di, unsigned int interface_pix_fmt,
+               ipu_di_clk_parent_t di_clk_parent, unsigned long di_clk_val, int bpp)
 {
        int ret;
 
-       ret = ipu_probe();
-       if (ret)
-               puts("Error initializing IPU\n");
-
-       ret = mxcfb_probe(gpixfmt, gdisp, gmode);
-       debug("Framebuffer at 0x%x\n", (unsigned int)panel.frameAdrs);
-
-       return (void *)&panel;
-}
-
-void video_set_lut(unsigned int index, /* color number */
-                       unsigned char r,    /* red */
-                       unsigned char g,    /* green */
-                       unsigned char b     /* blue */
-                       )
-{
-       return;
-}
+       default_bpp = bpp;
 
-int ipuv3_fb_init(struct fb_videomode const *mode,
-                 uint8_t disp,
-                 uint32_t pixfmt)
-{
-       gmode = mode;
-       gdisp = disp;
-       gpixfmt = pixfmt;
+       ret = ipu_probe(di, di_clk_parent, di_clk_val);
+       if (ret) {
+               printf("Error initializing IPU\n");
+               return ret;
+       }
 
-       return 0;
+       return mxcfb_probe(interface_pix_fmt, mode, di);
 }
index 03b0f88acfaa26cf930bbe8d6390b1b731de32b8..68293d2b75dcc019d56ca2e98e8864ed1088759c 100644 (file)
@@ -8,6 +8,7 @@
 #include <common.h>
 #include <malloc.h>
 #include <video_fb.h>
+#include <mxcfb.h>
 
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/clock.h>
@@ -21,6 +22,8 @@
 
 #define        PS2KHZ(ps)      (1000000000UL / (ps))
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static GraphicDevice panel;
 struct mxs_dma_desc desc;
 
@@ -44,15 +47,16 @@ __weak void mxsfb_system_setup(void)
  * Freescale mx23evk/mx28evk with a Seiko 4.3'' WVGA panel:
  * setenv videomode
  * video=ctfb:x:800,y:480,depth:24,mode:0,pclk:29851,
- *      le:89,ri:164,up:23,lo:10,hs:10,vs:10,sync:0,vmode:0
+ *      le:89,ri:164,up:23,lo:10,hs:10,vs:10,sync:0,vmode:0
  */
 
 static void mxs_lcd_init(GraphicDevice *panel,
                        struct ctfb_res_modes *mode, int bpp)
 {
        struct mxs_lcdif_regs *regs = (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
-       uint32_t word_len = 0, bus_width = 0;
-       uint8_t valid_data = 0;
+       uint32_t word_len, bus_width;
+       uint8_t valid_data;
+       uint32_t vctrl0 = 0;
 
        /* Kick in the LCDIF clock */
        mxs_set_lcdclk(PS2KHZ(mode->pixclock));
@@ -81,6 +85,9 @@ static void mxs_lcd_init(GraphicDevice *panel,
                bus_width = LCDIF_CTRL_LCD_DATABUS_WIDTH_8BIT;
                valid_data = 0xf;
                break;
+       default:
+               printf("Invalid color depth: %d\n", bpp);
+               hang();
        }
 
        writel(bus_width | word_len | LCDIF_CTRL_DOTCLK_MODE |
@@ -95,7 +102,19 @@ static void mxs_lcd_init(GraphicDevice *panel,
        writel((mode->yres << LCDIF_TRANSFER_COUNT_V_COUNT_OFFSET) | mode->xres,
                &regs->hw_lcdif_transfer_count);
 
-       writel(LCDIF_VDCTRL0_ENABLE_PRESENT | LCDIF_VDCTRL0_ENABLE_POL |
+       if (!(mode->sync & FB_SYNC_OE_LOW_ACT))
+               vctrl0 |= LCDIF_VDCTRL0_ENABLE_POL;
+
+       if (mode->sync & FB_SYNC_CLK_LAT_FALL)
+               vctrl0 |= LCDIF_VDCTRL0_DOTCLK_POL;
+
+       if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
+               vctrl0 |= LCDIF_VDCTRL0_HSYNC_POL;
+
+       if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
+               vctrl0 |= LCDIF_VDCTRL0_VSYNC_POL;
+
+       writel(vctrl0 | LCDIF_VDCTRL0_ENABLE_PRESENT |
                LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT |
                LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
                mode->vsync_len, &regs->hw_lcdif_vdctrl0);
@@ -135,7 +154,6 @@ void *video_hw_init(void)
 {
        int bpp = -1;
        char *penv;
-       void *fb;
        struct ctfb_res_modes mode;
 
        puts("Video: ");
@@ -179,18 +197,7 @@ void *video_hw_init(void)
 
        panel.memSize = mode.xres * mode.yres * panel.gdfBytesPP;
 
-       /* Allocate framebuffer */
-       fb = memalign(ARCH_DMA_MINALIGN,
-                     roundup(panel.memSize, ARCH_DMA_MINALIGN));
-       if (!fb) {
-               printf("MXSFB: Error allocating framebuffer!\n");
-               return NULL;
-       }
-
-       /* Wipe framebuffer */
-       memset(fb, 0, panel.memSize);
-
-       panel.frameAdrs = (u32)fb;
+       panel.frameAdrs = gd->fb_base;
 
        printf("%s\n", panel.modeIdent);
 
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..052e24f6cde67a615bfd9035fa1862f35ebcee74 100644 (file)
@@ -0,0 +1,7 @@
+config HW_WATCHDOG
+       bool "Generic SoC specific watchdog support"
+       depends on !MX6
+
+config IMX_WATCHDOG
+       bool "Freescale i.MX watchdog support"
+       depends on MX31 || MX35 || MX5 || MX6 || VF610 || LS102XA
index 1dc0f5aa101e4fabf9710563ce37cb21d1f9faf9..efad1432d607392584659efc5b822a9c5ce8473b 100644 (file)
@@ -5,14 +5,12 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
-obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
-ifneq (,$(filter $(SOC), mx31 mx35 mx5 mx6 vf610 ls102xa))
-obj-y += imx_watchdog.o
-endif
-obj-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
-obj-$(CONFIG_S5P)               += s5p_wdt.o
-obj-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
-obj-$(CONFIG_BFIN_WATCHDOG)  += bfin_wdt.o
-obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
-obj-$(CONFIG_DESIGNWARE_WATCHDOG) += designware_wdt.o
+obj-$(CONFIG_AT91SAM9_WATCHDOG)                += at91sam9_wdt.o
+obj-$(CONFIG_BFIN_WATCHDOG)            += bfin_wdt.o
+obj-$(CONFIG_DESIGNWARE_WATCHDOG)      += designware_wdt.o
+obj-$(CONFIG_FTWDT010_WATCHDOG)                += ftwdt010_wdt.o
+obj-$(CONFIG_IMX_WATCHDOG)             += imx_watchdog.o
+obj-$(CONFIG_OMAP_WATCHDOG)            += omap_wdt.o
+obj-$(CONFIG_S5P)                      += s5p_wdt.o
+obj-$(CONFIG_TNETV107X_WATCHDOG)       += tnetv107x_wdt.o
+obj-$(CONFIG_XILINX_TB_WATCHDOG)       += xilinx_tb_wdt.o
index d5993b4d26d6ba6018031cc5b31f7966d13a5ca8..3f6e5593ed0619aaa0dba7f812d8f7e85ac0ccdb 100644 (file)
@@ -56,12 +56,7 @@ void reset_cpu(ulong addr)
 {
        struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR;
 
-       writew(WCR_WDE, &wdog->wcr);
-       writew(0x5555, &wdog->wsr);
-       writew(0xaaaa, &wdog->wsr);     /* load minimum 1/2 second timeout */
        while (1) {
-               /*
-                * spin for .5 seconds before reset
-                */
+               writew(0, &wdog->wcr); /* clear SRS initiating SOFT reset */
        }
 }
index 5fe63f8025879a7fca596cd403a409f601ca97e8..3a180d5b6fa39526390c15425825762e8adc8e49 100644 (file)
@@ -52,4 +52,8 @@ config DEFAULT_DEVICE_TREE
          It can be overridden from the command line:
          $ make DEVICE_TREE=<device-tree-name>
 
+config FDT_FIXUP_PARTITIONS
+       bool
+       depends on MTD_PARTITIONS && OF_LIBFDT
+
 endmenu
index e8dee5357514c1cb33140da968626d8217f145ba..2cfd6cfbd7496263e4585cc3946868ab0d5b038b 100644 (file)
@@ -1,4 +1,7 @@
 /*
+ * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
+ * Terry Lv <r65388@freescale.com>
+ *
  * Copyright (C) Freescale Semiconductor, Inc. 2006.
  * Author: Jason Jin<Jason.jin@freescale.com>
  *         Zhang Wei<wei.zhang@freescale.com>
 
 #define AHCI_PCI_BAR           0x24
 #define AHCI_MAX_SG            56 /* hardware max is 64K */
+#define AHCI_MAX_CMD_SLOT      32
 #define AHCI_CMD_SLOT_SZ       32
 #define AHCI_MAX_CMD_SLOT      32
 #define AHCI_RX_FIS_SZ         256
 #define AHCI_CMD_TBL_HDR       0x80
 #define AHCI_CMD_TBL_CDB       0x40
-#define AHCI_CMD_TBL_SZ                AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16)
+#define AHCI_CMD_TBL_SZ                (AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16))
 #define AHCI_PORT_PRIV_DMA_SZ  (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT + \
                                AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ)
 #define AHCI_CMD_ATAPI         (1 << 5)
@@ -152,7 +156,7 @@ struct ahci_probe_ent {
        u32     host_flags;
        u32     host_set_flags;
        u32     mmio_base;
-       u32     pio_mask;
+       u32     pio_mask;
        u32     udma_mask;
        u32     flags;
        u32     cap;    /* cache of HOST_CAP register */
index 3b96b8209a10b09d2cdcdf1f559c5fa2787831d7..d4f4f0685b96e3d872870eb77725c44d4f2d27cc 100644 (file)
  * an error value of -1.
  */
 
+enum gpio_flags {
+       GPIOFLAG_INPUT,
+       GPIOFLAG_OUTPUT_INIT_LOW,
+       GPIOFLAG_OUTPUT_INIT_HIGH,
+};
+
+struct gpio {
+       unsigned int gpio;
+       enum gpio_flags flags;
+       const char *label;
+};
+
 /**
  * @deprecated Please use driver model instead
  * Request a GPIO. This should be called before any of the other functions
  */
 int gpio_request(unsigned gpio, const char *label);
 
+/**
+ * @deprecated Please use driver model instead
+ * Request a GPIO and configure it
+ * @param gpios        pointer to array of gpio defs
+ * @param count        number of GPIOs to set up
+ */
+int gpio_request_one(unsigned gpio, enum gpio_flags flags, const char *label);
+
+/**
+ * Request a set of GPIOs and configure them
+ * @param gpios        pointer to array of gpio defs
+ * @param count        number of GPIOs to set up
+ */
+int gpio_request_array(const struct gpio *gpios, int count);
+
 /**
  * @deprecated Please use driver model instead
  * Stop using the GPIO.  This function should not alter pin configuration.
@@ -57,6 +84,14 @@ int gpio_request(unsigned gpio, const char *label);
  */
 int gpio_free(unsigned gpio);
 
+/**
+ * @deprecated Please use driver model instead
+ * Release a set of GPIOs
+ * @param gpios        pointer to array of gpio defs
+ * @param count        number of GPIOs to set up
+ */
+int gpio_free_array(const struct gpio *gpios, int count);
+
 /**
  * @deprecated Please use driver model instead
  * Make a GPIO an input.
diff --git a/include/configs/triton320.h b/include/configs/triton320.h
new file mode 100644 (file)
index 0000000..5af7c1a
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * (C) Copyright 2002
+ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * Configuation settings for the TRITON320 board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_CPU_MONAHANS    1       /* Intel Monahan CPU    */
+#define CONFIG_TRITON320       1       /* Zylonite board       */
+
+/* #define CONFIG_LCD          1 */
+#ifdef CONFIG_LCD
+#define CONFIG_SHARP_LM8V31
+#endif
+/* #define CONFIG_MMC          1 */
+#define BOARD_LATE_INIT                1
+
+#define CONFIG_SKIP_RELOCATE_UBOOT     1
+#undef CONFIG_SKIP_LOWLEVEL_INIT  
+#undef CONFIG_USE_IRQ                  /* we don't need IRQ/FIQ stuff */
+
+/*
+ * Size of malloc() pool
+ */
+#define CFG_MALLOC_LEN     (CFG_ENV_SIZE + 256*1024)
+#define CFG_GBL_DATA_SIZE      512     /* size in bytes reserved for initial data */
+
+/*
+ * Hardware drivers
+ */
+
+
+#define CONFIG_DRIVER_DM9000           1
+#define CONFIG_DM9000_BASE             0x10000300
+#define DM9000_IO                      CONFIG_DM9000_BASE
+#define DM9000_DATA                    (CONFIG_DM9000_BASE+0x8000)
+#define CONFIG_DM9000_USE_16BIT
+
+
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_FFUART         1
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE                38400
+
+#if 0
+# define CONFIG_COMMANDS       CFG_CMD_AUTOSCRIPT      \
+               |       CFG_CMD_BDI             \
+               |       CFG_CMD_BOOTD           \
+               |       CFG_CMD_CONSOLE         \
+               |       CFG_CMD_ECHO            \
+               |       CFG_CMD_ENV             \
+               |       CFG_CMD_IMI             \
+               |       CFG_CMD_ITEST           \
+               |       CFG_CMD_LOADB           \
+               |       CFG_CMD_LOADS           \
+               |       CFG_CMD_MEMORY          \
+               |       CFG_CMD_NAND            \
+               |       CFG_CMD_REGINFO         \
+               |       CFG_CMD_RUN     \
+               &       ~(CFG_CMD_JFFS2 | CFG_CMD_FLASH | CFG_CMD_IMLS)
+#endif
+
+#define CONFIG_COMMANDS        ((CONFIG_CMD_DFL|       \
+                        CFG_CMD_NAND   |       \
+                        CFG_CMD_JFFS2  |       \
+                        CFG_CMD_PING   |       \
+                        CFG_CMD_DHCP)  &       \
+                       ~(CFG_CMD_FLASH |       \
+                         CFG_CMD_IMLS))
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+#define CONFIG_BOOTDELAY                       3
+#define CONFIG_BOOTCOMMAND                     "bootm 80000"
+#define CONFIG_BOOTARGS                                "root=/dev/mtdblock1 rootfstype=jffs2 console=ttyS0,38400"
+#define CONFIG_BOOT_RETRY_TIME         -1
+#define CONFIG_BOOT_RETRY_MIN          60
+#define CONFIG_RESET_TO_RETRY
+#define CONFIG_AUTOBOOT_PROMPT         "autoboot in %d seconds\n"
+#define CONFIG_AUTOBOOT_DELAY_STR      " "
+#define CONFIG_AUTOBOOT_STOP_STR       "system"
+
+#define CONFIG_ETHADDR                 ff:ff:ff:ff:ff:ff
+#define CONFIG_NETMASK                 255.255.255.255
+#define CONFIG_IPADDR                  0.0.0.0
+#define CONFIG_SERVERIP                        0.0.0.0
+#define CONFIG_CMDLINE_TAG             1
+#define CONFIG_SETUP_MEMORY_TAGS       1
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_TIMESTAMP
+#define CONFIG_USE_MAC_FROM_ENV
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE   230400          /* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX  2               /* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_HUSH_PARSER                1
+#define CFG_PROMPT_HUSH_PS2    "> "
+
+#define CFG_LONGHELP                           /* undef to save memory         */
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT             "$ "            /* Monitor Command Prompt */
+#else
+#define CFG_PROMPT             "=> "           /* Monitor Command Prompt */
+#endif
+#define CFG_CBSIZE             256             /* Console I/O Buffer Size      */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define CFG_MAXARGS            16              /* max number of command args   */
+#define CFG_BARGSIZE           CFG_CBSIZE      /* Boot Argument Buffer Size    */
+#define CFG_DEVICE_NULLDEV     1
+
+#define CFG_MEMTEST_START      0x00400000      /* memtest works on     */
+#define CFG_MEMTEST_END                0x00800000      /* 4 ... 8 MB in DRAM   */
+
+#undef CFG_CLKS_IN_HZ          /* everything, incl board info, in Hz */
+
+#define CFG_HZ                 3250000         /* incrementer freq: 3.25 MHz */
+
+/* Monahans Core Frequency */
+#define CFG_MONAHANS_RUN_MODE_OSC_RATIO                31 /* valid values: 8, 16, 24, 31 */
+#define CFG_MONAHANS_TURBO_RUN_MODE_RATIO      2  /* valid values: 1, 2 */
+
+                                               /* valid baudrates */
+#define CFG_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200 }
+
+/* #define CFG_MMC_BASE                0xF0000000 */
+
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE       (128*1024)      /* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ   (4*1024)        /* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ   (4*1024)        /* FIQ stack */
+#endif
+
+/*
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS   1          /* we have 1 banks of DRAM */
+#define PHYS_SDRAM_1           0x80000000 /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE      0x04000000 /* 64 MB */
+
+#define CFG_DRAM_BASE          PHYS_SDRAM_1
+#define CFG_DRAM_SIZE          PHYS_SDRAM_1_SIZE
+
+
+#define CFG_LOAD_ADDR          (PHYS_SDRAM_1 + 0x100000) /* default load address */
+
+#define CFG_SKIP_DRAM_SCRUB
+
+/*
+ * NAND Flash
+ */
+/* Use the new NAND code. (BOARDLIBS = drivers/nand/libnand.a required) */
+#define CONFIG_NEW_NAND_CODE
+#define CFG_NAND0_BASE         0x0
+#undef CFG_NAND1_BASE
+
+#define CONFIG_MTD_NAND_ECC_JFFS2 1
+
+#define CFG_NAND_BASE_LIST     { CFG_NAND0_BASE }
+#define CFG_MAX_NAND_DEVICE    1       /* Max number of NAND devices */
+
+/* nand timeout values */
+#define CFG_NAND_PROG_ERASE_TO 9000
+#define CFG_NAND_OTHER_TO      2000
+#define CFG_NAND_SENDCMD_RETRY 3
+#undef NAND_ALLOW_ERASE_ALL    /* Allow erasing bad blocks - don't use */
+
+/* NAND Timing Parameters (in ns) */
+#define NAND_TIMING_tCH                10
+#define NAND_TIMING_tCS                0
+#define NAND_TIMING_tWH                20
+#define NAND_TIMING_tWP                40
+
+#define NAND_TIMING_tRH                20
+#define NAND_TIMING_tRP                40
+
+#define NAND_TIMING_tR         11123
+#define NAND_TIMING_tWHR       100
+#define NAND_TIMING_tAR                10
+
+/* NAND debugging */
+#if 0
+#define        CFG_DFC_DEBUG1          /* useful */
+#define                CFG_DFC_DEBUG2          /* noisy */
+#define        CFG_DFC_DEBUG3          /* extremly noisy  */
+#else
+#undef         CFG_DFC_DEBUG1          /* useful */
+#undef         CFG_DFC_DEBUG2          /* noisy */
+#undef         CFG_DFC_DEBUG3          /* extremly noisy  */
+#endif
+
+#define CONFIG_MTD_DEBUG       0
+#define CONFIG_MTD_DEBUG_VERBOSE 0
+
+#define ADDR_COLUMN            1
+#define ADDR_PAGE              2
+#define ADDR_COLUMN_PAGE       3
+
+#define NAND_ChipID_UNKNOWN    0x00
+#define NAND_MAX_FLOORS                1
+#define NAND_MAX_CHIPS         1
+
+#define CFG_NO_FLASH           1
+
+#define CFG_ENV_IS_IN_NAND     1
+#define CFG_ENV_OFFSET         0x60000
+#undef CFG_ENV_OFFSET_REDUND
+#define CFG_ENV_SIZE           0x20000
+
+#define CONFIG_JFFS2_NAND 1
+#define CONFIG_JFFS2_NAND_DEV "nand0"                  /* nand device jffs2 lives on */
+#define CONFIG_JFFS2_NAND_OFF 0x80000                  /* start of jffs2 partition */
+#define CONFIG_JFFS2_NAND_SIZE 64*1024*1024            /* size of jffs2 partition */
+
+
+/* mtdparts command line support */
+#define CONFIG_JFFS2_CMDLINE
+#define MTDIDS_DEFAULT         "nand0=triton320-nand"
+#define MTDPARTS_DEFAULT       "mtdparts=triton320-nand:128k(sbootl),256k(u-boot),128k(env),2m(linux_kernel),83456k(userfs),32m(wince);" 
+
+#endif /* __CONFIG_H */
index 118f5bae7265e6e1c79d21ef8584f9a2429901c2..1d8b687905f20daf3890312908e85ee753a5dd1b 100644 (file)
  * Flash & Environment
  */
 /* No NOR flash present */
-#define CONFIG_SYS_NO_FLASH
 #define        CONFIG_ENV_IS_IN_NAND
 #define        CONFIG_ENV_OFFSET       CONFIG_SYS_MONITOR_LEN
 #define CONFIG_ENV_SIZE                (128 * 1024)    /* 128 kB NAND block size */
 #define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
 
 /* NAND */
-#define CONFIG_NAND_MXC
 #define CONFIG_MXC_NAND_REGS_BASE      (0xBB000000)
 #define CONFIG_SYS_MAX_NAND_DEVICE     1
 #define CONFIG_SYS_NAND_BASE           (0xBB000000)
 
 /* U-Boot commands */
 #include <config_cmd_default.h>
-#define CONFIG_CMD_NAND
-#define CONFIG_CMD_CACHE
 
 /*
  * Ethernet
  */
-#define CONFIG_FEC_MXC
-#define CONFIG_FEC_MXC_PHYADDR         0x1f
-#define CONFIG_MII
-#define CONFIG_CMD_NET
 #define CONFIG_BOARD_LATE_INIT
 #define CONFIG_ENV_OVERWRITE
 
diff --git a/include/configs/tx28.h b/include/configs/tx28.h
new file mode 100644 (file)
index 0000000..fe7cd19
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2012 <LW@KARO-electronics.de>
+ *
+ * SPDX-License-Identifier:      GPL-2.0
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MX28                    /* must be defined before including regs-base.h */
+
+#include <linux/sizes.h>
+#include <asm/arch/regs-base.h>
+
+/*
+ * Ka-Ro TX28 board - SoC configuration
+ */
+#define CONFIG_MXS_GPIO                                        /* GPIO control */
+#define CONFIG_SYS_HZ                  1000            /* Ticks per second */
+#define PHYS_SDRAM_1_SIZE              CONFIG_SDRAM_SIZE
+#ifdef CONFIG_TX28_S
+#define TX28_MOD_SUFFIX                        "1"
+#else
+#define CONFIG_SYS_SPL_FIXED_BATT_SUPPLY
+#define TX28_MOD_SUFFIX                        "0"
+#endif
+#define IRAM_BASE_ADDR                 0x00000000
+
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SHOW_ACTIVITY
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_ARCH_MISC_INIT          /* init vector table after relocation */
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_BOARD_EARLY_INIT_F
+
+/* LCD Logo and Splash screen support */
+#define CONFIG_LCD
+#ifdef CONFIG_LCD
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_VIDEO_MXS
+#define CONFIG_LCD_LOGO
+#define LCD_BPP                                LCD_COLOR32
+#define CONFIG_CMD_BMP
+#define CONFIG_VIDEO_BMP_RLE8
+#endif /* CONFIG_LCD */
+#endif /* CONFIG_SPL_BUILD */
+
+/*
+ * Memory configuration options
+ */
+#define CONFIG_NR_DRAM_BANKS           0x1             /* 1 bank of SDRAM */
+#define PHYS_SDRAM_1                   0x40000000      /* SDRAM Bank #1 */
+#define CONFIG_STACKSIZE               SZ_64K
+#define CONFIG_SYS_MALLOC_LEN          SZ_4M
+#define CONFIG_SYS_MEMTEST_START       PHYS_SDRAM_1    /* Memtest start address */
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START + SZ_4M)
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT              "TX28 U-Boot > "
+#define CONFIG_SYS_CBSIZE              2048            /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                                       /* Print buffer size */
+#define CONFIG_SYS_MAXARGS             256             /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
+                                       /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE                /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE           /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING         /* Command history etc */
+
+#define CONFIG_SYS_64BIT_VSPRINTF
+
+/*
+ * Flattened Device Tree (FDT) support
+*/
+#ifdef CONFIG_OF_LIBFDT
+#endif
+
+/*
+ * Boot Linux
+ */
+#define xstr(s)                                str(s)
+#define str(s)                         #s
+#define __pfx(x, s)                    (x##s)
+#define _pfx(x, s)                     __pfx(x, s)
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY               3
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_SYS_AUTOLOAD            "no"
+#define CONFIG_BOOTFILE                        "uImage"
+#define CONFIG_BOOTARGS                        "init=/linuxrc console=ttyAMA0,115200 ro debug panic=1"
+#define CONFIG_BOOTCOMMAND             "run bootcmd_${boot_mode} bootm_cmd"
+#ifdef CONFIG_TX28_S
+#define CONFIG_LOADADDR                        41000000
+#else
+#define CONFIG_LOADADDR                        43000000
+#endif
+#define CONFIG_FDTADDR                 41000000
+#define CONFIG_SYS_LOAD_ADDR           _pfx(0x, CONFIG_LOADADDR)
+#define CONFIG_SYS_FDT_ADDR            _pfx(0x, CONFIG_FDTADDR)
+#define CONFIG_U_BOOT_IMG_SIZE         SZ_1M
+
+/*
+ * Extra Environment Settings
+ */
+#ifdef CONFIG_ENV_IS_NOWHERE
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       "autostart=no\0"                                                \
+       "autoload=no\0"                                                 \
+       "bootdelay=-1\0"                                                \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"
+#else
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock3 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/mmcblk0p3 rootwait\0"                               \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs;nboot linux\0"\
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=nand\0"                                              \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"                       \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=VGA\0"
+#endif /*  CONFIG_ENV_IS_NOWHERE */
+
+#define MTD_NAME                       "gpmi-nand"
+#define MTDIDS_DEFAULT                 "nand0=" MTD_NAME
+
+/*
+ * U-Boot Commands
+ */
+#include <config_cmd_default.h>
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_CLOCK             24000000
+#define CONFIG_PL01x_PORTS     {       \
+       (void *)MXS_UARTDBG_BASE,       \
+       }
+#define CONFIG_CONS_INDEX              0               /* do not change! */
+#define CONFIG_BAUDRATE                        115200          /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200, }
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/*
+ * Ethernet Driver
+ */
+#ifdef CONFIG_FEC_MXC
+/* This is required for the FEC driver to work with cache enabled */
+#define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
+#define CONFIG_SYS_CACHELINE_SIZE      32
+
+#ifndef CONFIG_TX28_S
+#else
+#define IMX_FEC_BASE                   MXS_ENET0_BASE
+#endif
+
+#define CONFIG_FEC_XCV_TYPE            RMII
+#define CONFIG_NET_MULTI
+#define CONFIG_CMD_MII
+/* Add for working with "strict" DHCP server */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_RANDOM_ID
+#endif
+
+#ifndef CONFIG_ENV_IS_NOWHERE
+/* define one of the following options:
+*/
+#endif
+#define CONFIG_ENV_OVERWRITE
+
+/*
+ * NAND flash driver
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_SYS_NAND_BLOCK_SIZE     SZ_128K
+#define CONFIG_NAND_MXS
+#define CONFIG_APBH_DMA
+#define CONFIG_APBH_DMA_BURST
+#define CONFIG_APBH_DMA_BURST8
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    CONFIG_SYS_NAND_BLOCK_SIZE
+#define CONFIG_SYS_MXS_DMA_CHANNEL     4
+#define CONFIG_SYS_NAND_MAX_CHIPS      0x1
+#define CONFIG_SYS_MAX_NAND_DEVICE     0x1
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_BASE           0x00000000
+#else
+#undef CONFIG_ENV_IS_IN_NAND
+#endif /* CONFIG_CMD_NAND */
+
+#ifdef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET              (CONFIG_U_BOOT_IMG_SIZE + CONFIG_SYS_NAND_U_BOOT_OFFS)
+#define CONFIG_ENV_SIZE                        SZ_128K
+#define CONFIG_ENV_RANGE               (3 * CONFIG_SYS_NAND_BLOCK_SIZE)
+#endif /* CONFIG_ENV_IS_IN_NAND */
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+#define CONFIG_SYS_ENV_PART_STR                xstr(CONFIG_SYS_ENV_PART_SIZE)  \
+       "(env),"                                                        \
+       xstr(CONFIG_SYS_ENV_PART_SIZE)                                  \
+       "(env2),"
+#define CONFIG_SYS_USERFS_PART_STR     xstr(CONFIG_SYS_USERFS_PART_SIZE2) "(userfs)"
+#else
+#define CONFIG_SYS_ENV_PART_STR                xstr(CONFIG_SYS_ENV_PART_SIZE)  \
+       "(env),"
+#define CONFIG_SYS_USERFS_PART_STR     xstr(CONFIG_SYS_USERFS_PART_SIZE) "(userfs)"
+#endif /* CONFIG_ENV_OFFSET_REDUND */
+
+/*
+ * MMC Driver
+ */
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MXS_MMC
+#define CONFIG_BOUNCE_BUFFER
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_CMD_EXT2
+
+/*
+ * Environments on MMC
+ */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV         0
+/* Associated with the MMC layout defined in mmcops.c */
+#define CONFIG_ENV_OFFSET              SZ_1K
+#define CONFIG_ENV_SIZE                        (SZ_128K - CONFIG_ENV_OFFSET)
+#define CONFIG_DYNAMIC_MMC_DEVNO
+#endif /* CONFIG_ENV_IS_IN_MMC */
+#else
+#undef CONFIG_ENV_IS_IN_MMC
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_ENV_IS_NOWHERE
+#undef CONFIG_ENV_SIZE
+#define CONFIG_ENV_SIZE                        SZ_4K
+#endif
+
+#define MTDPARTS_DEFAULT               "mtdparts=" MTD_NAME ":"        \
+       "1m@" xstr(CONFIG_SYS_NAND_U_BOOT_OFFS) "(u-boot),"             \
+       CONFIG_SYS_ENV_PART_STR                                         \
+       "6m(linux),32m(rootfs)," CONFIG_SYS_USERFS_PART_STR             \
+       ",512k@" xstr(CONFIG_SYS_NAND_DTB_OFFSET) "(dtb)"               \
+       ",512k@" xstr(CONFIG_SYS_NAND_BBT_OFFSET) "(bbt)ro"
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+                                       GENERATED_GBL_DATA_SIZE)
+
+/* Defines for SPL */
+#define CONFIG_SPL
+#define CONFIG_SPL_START_S_PATH                "arch/arm/cpu/arm926ejs/mxs"
+#define CONFIG_SPL_LDSCRIPT            "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds"
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SYS_SPL_VDDD_VAL                1500
+#define CONFIG_SYS_SPL_BATT_BO_LEVEL   2800
+#define CONFIG_SYS_SPL_VDDMEM_VAL      0       /* VDDMEM is not utilized on TX28 */
+
+#endif /* __CONFIGS_TX28_H */
diff --git a/include/configs/tx48.h b/include/configs/tx48.h
new file mode 100644 (file)
index 0000000..9c21e10
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * tx48.h
+ *
+ * Copyright (C) 2012-2014 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * based on: am335x_evm
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:      GPL-2.0
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_AM33XX                  /* must be set before including omap.h */
+
+#include <linux/sizes.h>
+#include <asm/arch/omap.h>
+
+/*
+ * Ka-Ro TX48 board - SoC configuration
+ */
+#define CONFIG_OMAP
+#define CONFIG_AM33XX_GPIO
+#define CONFIG_SYS_HZ                  1000    /* Ticks per second */
+
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#define CONFIG_SHOW_ACTIVITY
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_LATE_INIT
+
+/* LCD Logo and Splash screen support */
+#define CONFIG_LCD
+#ifdef CONFIG_LCD
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_AM335X_LCD
+#define DAVINCI_LCD_CNTL_BASE          0x4830e000
+#define CONFIG_LCD_LOGO
+#define LCD_BPP                                LCD_COLOR32
+#define CONFIG_CMD_BMP
+#define CONFIG_VIDEO_BMP_RLE8
+#endif /* CONFIG_LCD */
+#endif /* CONFIG_SPL_BUILD */
+
+/* Clock Defines */
+#define V_OSCK                         24000000  /* Clock output from T2 */
+#define V_SCLK                         V_OSCK
+
+/*
+ * Memory configuration options
+ */
+#define CONFIG_SYS_SDRAM_DDR3
+#define CONFIG_NR_DRAM_BANKS           0x1             /* '1' would be converted to 'y' by define2mk.sed */
+#define PHYS_SDRAM_1                   0x80000000      /* SDRAM Bank #1 */
+#define CONFIG_MAX_RAM_BANK_SIZE       SZ_1G
+
+#define CONFIG_STACKSIZE               SZ_64K
+#define CONFIG_SYS_MALLOC_LEN          SZ_4M
+
+#define CONFIG_SYS_MEMTEST_START       (PHYS_SDRAM_1 + SZ_64M)
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START + SZ_8M)
+
+#define CONFIG_SYS_CACHELINE_SIZE      64
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT              "TX48 U-Boot > "
+#define CONFIG_SYS_CBSIZE              2048    /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                               /* Print buffer size */
+#define CONFIG_SYS_MAXARGS             256     /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE                        /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE                   /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING                 /* Command history etc */
+
+#define CONFIG_SYS_64BIT_VSPRINTF
+
+/*
+ * Flattened Device Tree (FDT) support
+*/
+
+/*
+ * Boot Linux
+ */
+#define xstr(s)                                str(s)
+#define str(s)                         #s
+#define __pfx(x, s)                    (x##s)
+#define _pfx(x, s)                     __pfx(x, s)
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY               3
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_SYS_AUTOLOAD            "no"
+#define CONFIG_BOOTFILE                        "uImage"
+#define CONFIG_BOOTARGS                        "init=/linuxrc console=ttyO0,115200 ro debug panic=1"
+#define CONFIG_BOOTCOMMAND             "run bootcmd_${boot_mode} bootm_cmd"
+#define CONFIG_LOADADDR                        83000000
+#define CONFIG_FDTADDR                 81000000
+#define CONFIG_SYS_LOAD_ADDR           _pfx(0x, CONFIG_LOADADDR)
+#define CONFIG_SYS_FDT_ADDR            _pfx(0x, CONFIG_FDTADDR)
+#define CONFIG_U_BOOT_IMG_SIZE         SZ_1M
+
+/*
+ * Extra Environment Settings
+ */
+#define CONFIG_SYS_CPU_CLK_STR         xstr(CONFIG_SYS_MPU_CLK)
+
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock4 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/mmcblk0p2 rootwait\0"                               \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs"              \
+       ";nboot linux\0"                                                \
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=nand\0"                                              \
+       "cpu_clk=" CONFIG_SYS_CPU_CLK_STR "\0"                          \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"                       \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=VGA\0"
+
+#define MTD_NAME                       "omap2-nand.0"
+#define MTDIDS_DEFAULT                 "nand0=" MTD_NAME
+
+/*
+ * U-Boot Commands
+ */
+#include <config_cmd_default.h>
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_REG_SIZE    (-4)
+#define CONFIG_SYS_NS16550_CLK         48000000
+#define CONFIG_SYS_NS16550_COM1                0x44e09000      /* UART0 */
+#define CONFIG_SYS_NS16550_COM2                0x48022000      /* UART1 */
+#define CONFIG_SYS_NS16550_COM6                0x481aa000      /* UART5 */
+
+#define CONFIG_SYS_NS16550_COM3                0x481aa000      /* UART2 */
+#define CONFIG_SYS_NS16550_COM4                0x481aa000      /* UART3 */
+#define CONFIG_SYS_NS16550_COM5                0x481aa000      /* UART4 */
+#define CONFIG_CONS_INDEX              1               /* one based! */
+#define CONFIG_BAUDRATE                        115200          /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200, }
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/*
+ * Ethernet Driver
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_DRIVER_TI_CPSW
+#define CONFIG_NET_MULTI
+#define CONFIG_PHY_GIGE
+#define CONFIG_CMD_MII
+/* Add for working with "strict" DHCP server */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#endif
+
+/*
+ * NAND flash driver
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_NAND_OMAP_GPMC
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SYS_GPMC_PREFETCH_ENABLE
+#endif
+#define GPMC_NAND_ECC_LP_x8_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT_KERNEL GPMC_NAND_HW_ECC_LAYOUT
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    0x20000
+#define CONFIG_SYS_NAND_PAGE_SIZE      2048
+#define CONFIG_SYS_NAND_OOBSIZE                64
+#define CONFIG_SYS_NAND_ECCSIZE                512
+#define CONFIG_SYS_NAND_ECCBYTES       14
+#define CONFIG_SYS_NAND_MAX_CHIPS      0x1
+#define CONFIG_SYS_NAND_MAXBAD         20 /* Max. number of bad blocks guaranteed by manufacturer */
+#define CONFIG_SYS_MAX_NAND_DEVICE     0x1
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#ifdef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_OFFSET              (CONFIG_U_BOOT_IMG_SIZE + CONFIG_SYS_NAND_U_BOOT_OFFS)
+#define CONFIG_ENV_SIZE                        SZ_128K
+#define CONFIG_ENV_RANGE               0x60000
+#endif /* CONFIG_ENV_IS_IN_NAND */
+#define CONFIG_SYS_NAND_BASE           0x00100000
+#define CONFIG_SYS_NAND_SIZE           SZ_128M
+#define NAND_BASE                      CONFIG_SYS_NAND_BASE
+#endif /* CONFIG_CMD_NAND */
+
+/*
+ * MMC Driver
+ */
+#ifdef CONFIG_CMD_MMC
+#ifndef CONFIG_ENV_IS_IN_NAND
+#endif
+#define CONFIG_OMAP_HSMMC
+#define CONFIG_OMAP_MMC_DEV_1
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_CMD_EXT2
+
+/*
+ * Environments on MMC
+ */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV         0
+#define CONFIG_ENV_OVERWRITE
+/* Associated with the MMC layout defined in mmcops.c */
+#define CONFIG_ENV_OFFSET              SZ_1K
+#define CONFIG_ENV_SIZE                        (SZ_128K - CONFIG_ENV_OFFSET)
+#define CONFIG_DYNAMIC_MMC_DEVNO
+#endif /* CONFIG_ENV_IS_IN_MMC */
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+#define MTDPARTS_DEFAULT               "mtdparts=" MTD_NAME ":"        \
+       "128k(u-boot-spl),"                                             \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),"                                                        \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env2),6m(linux),32m(rootfs),89216k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+#else
+#define MTDPARTS_DEFAULT               "mtdparts=" MTD_NAME ":"        \
+       "128k(u-boot-spl),"                                             \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),6m(linux),32m(rootfs),89600k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
+#define SRAM0_SIZE                     SZ_64K
+#define OCMC_SRAM_BASE                 0x40300000
+#define CONFIG_SPL_STACK               (OCMC_SRAM_BASE + 0xb800)
+#define CONFIG_SYS_INIT_SP_ADDR                (PHYS_SDRAM_1 + SZ_32K)
+
+ /* Platform/Board specific defs */
+#define CONFIG_SYS_TIMERBASE           0x48040000      /* Use Timer2 */
+#define CONFIG_SYS_PTV                 2       /* Divisor: 2^(PTV+1) => 8 */
+
+/* Defines for SPL */
+#define CONFIG_SPL
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_MAX_SIZE            (SRAM_SCRATCH_SPACE_ADDR - CONFIG_SPL_TEXT_BASE)
+#define CONFIG_SPL_GPIO_SUPPORT
+#ifdef CONFIG_NAND_OMAP_GPMC
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_ECC
+#define CONFIG_SPL_NAND_AM33XX_BCH
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_PAGE_COUNT     (CONFIG_SYS_NAND_BLOCK_SIZE /   \
+                                       CONFIG_SYS_NAND_PAGE_SIZE)
+#define CONFIG_SYS_NAND_BLOCK_SIZE     SZ_128K
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS  NAND_LARGE_BADBLOCK_POS
+#define CONFIG_SYS_NAND_ECCPOS         { 2, 3, 4, 5, 6, 7, 8, 9, \
+                                        10, 11, 12, 13, 14, 15, 16, 17, \
+                                        18, 19, 20, 21, 22, 23, 24, 25, \
+                                        26, 27, 28, 29, 30, 31, 32, 33, \
+                                        34, 35, 36, 37, 38, 39, 40, 41, \
+                                        42, 43, 44, 45, 46, 47, 48, 49, \
+                                        50, 51, 52, 53, 54, 55, 56, 57, }
+#endif
+
+#define CONFIG_SPL_BSS_START_ADDR      PHYS_SDRAM_1
+#define CONFIG_SPL_BSS_MAX_SIZE                SZ_512K
+
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR        0x300 /* address 0x60000 */
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_YMODEM_SUPPORT
+#define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/omap-common/u-boot-spl.lds"
+
+/*
+ * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
+ * 64 bytes before this address should be set aside for u-boot.img's
+ * header. That is 0x800FFFC0--0x80100000 should not be used for any
+ * other needs.
+ */
+#define CONFIG_SYS_SPL_MALLOC_START    (PHYS_SDRAM_1 + SZ_2M + SZ_32K)
+#define CONFIG_SYS_SPL_MALLOC_SIZE     SZ_1M
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/tx51.h b/include/configs/tx51.h
new file mode 100644 (file)
index 0000000..74a9076
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2012-2014 <LW@KARO-electronics.de>
+ *
+ * SPDX-License-Identifier:      GPL-2.0
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_MX51                    /* must be set before including imx-regs.h */
+
+#include <linux/sizes.h>
+#include <asm/arch/imx-regs.h>
+
+/*
+ * Ka-Ro TX51 board - SoC configuration
+ */
+#define CONFIG_SYS_MX5_IOMUX_V3
+#define CONFIG_MXC_GPIO                        /* GPIO control */
+#define CONFIG_SYS_MX5_HCLK            24000000
+#define CONFIG_SYS_DDR_CLKSEL          0
+#define CONFIG_SYS_HZ                  1000    /* Ticks per second */
+#define CONFIG_SHOW_ACTIVITY
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_BOARD_EARLY_INIT_F
+
+#if CONFIG_SYS_CPU_CLK == 600
+#define TX51_MOD_PREFIX                        "6"
+#elif CONFIG_SYS_CPU_CLK == 800
+#define TX51_MOD_PREFIX                        "8"
+#define CONFIG_MX51_PLL_ERRATA
+#else
+#error Invalid CPU clock
+#endif
+
+/* LCD Logo and Splash screen support */
+#define CONFIG_LCD
+#ifdef CONFIG_LCD
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_VIDEO_IPUV3
+#define CONFIG_IPUV3_CLK               133000000
+#define CONFIG_LCD_LOGO
+#define LCD_BPP                                LCD_COLOR32
+#define CONFIG_CMD_BMP
+#define CONFIG_VIDEO_BMP_RLE8
+#endif /* CONFIG_LCD */
+
+/*
+ * Memory configuration options
+ */
+#define PHYS_SDRAM_1                   0x90000000      /* Base address of bank 1 */
+#define PHYS_SDRAM_1_SIZE              SZ_128M
+#if CONFIG_NR_DRAM_BANKS > 1
+#define PHYS_SDRAM_2                   0x98000000      /* Base address of bank 2 */
+#define PHYS_SDRAM_2_SIZE              SZ_128M
+#endif
+#define CONFIG_STACKSIZE               SZ_128K
+#define CONFIG_SYS_MALLOC_LEN          SZ_8M
+#define CONFIG_SYS_MEMTEST_START       PHYS_SDRAM_1    /* Memtest start address */
+#define CONFIG_SYS_MEMTEST_END         (PHYS_SDRAM_1 + SZ_4M)  /* 4 MB RAM test */
+#define CONFIG_SYS_SDRAM_CLK           166
+#define CONFIG_SYS_CLKTL_CBCDR         0x01e35100
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT              "TX51 U-Boot > "
+#define CONFIG_SYS_CBSIZE              2048    /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                               /* Print buffer size */
+#define CONFIG_SYS_MAXARGS             256     /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE                        /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE                   /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING                 /* Command history etc */
+
+#define CONFIG_SYS_64BIT_VSPRINTF
+
+/*
+ * Flattened Device Tree (FDT) support
+*/
+
+/*
+ * Boot Linux
+ */
+#define xstr(s)                                str(s)
+#define str(s)                         #s
+#define __pfx(x, s)                    (x##s)
+#define _pfx(x, s)                     __pfx(x, s)
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY               3
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_SYS_AUTOLOAD            "no"
+#define CONFIG_BOOTFILE                        "uImage"
+#define CONFIG_BOOTARGS                        "init=/linuxrc console=ttymxc0,115200 ro debug panic=1"
+#define CONFIG_BOOTCOMMAND             "run bootcmd_${boot_mode} bootm_cmd"
+#define CONFIG_LOADADDR                        94000000
+#define CONFIG_FDTADDR                 91000000
+#define CONFIG_SYS_LOAD_ADDR           _pfx(0x, CONFIG_LOADADDR)
+#define CONFIG_SYS_FDT_ADDR            _pfx(0x, CONFIG_FDTADDR)
+#define CONFIG_U_BOOT_IMG_SIZE         SZ_1M
+
+/*
+ * Extra Environment Settings
+ */
+#define CONFIG_SYS_CPU_CLK_STR         xstr(CONFIG_SYS_CPU_CLK)
+
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock3 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/mmcblk0p2 rootwait\0"                               \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs"              \
+       ";nboot linux\0"                                                \
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=nand\0"                                              \
+       "cpu_clk=" CONFIG_SYS_CPU_CLK_STR "\0"                          \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"                       \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=VGA\0"
+
+#define MTD_NAME                       "mxc_nand"
+#define MTDIDS_DEFAULT                 "nand0=" MTD_NAME
+
+/*
+ * U-Boot Commands
+ */
+#include <config_cmd_default.h>
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE           UART1_BASE
+#define CONFIG_MXC_GPIO
+#define CONFIG_BAUDRATE                        115200          /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200, }
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/*
+ * Ethernet Driver
+ */
+#ifdef CONFIG_FEC_MXC
+#define IMX_FEC_BASE                   FEC_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE            MII100
+#define CONFIG_CMD_MII
+/* Add for working with "strict" DHCP server */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_DNS
+#endif
+
+/*
+ * NAND flash driver
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_MXC_NAND_REGS_BASE      NFC_BASE_ADDR_AXI
+#define CONFIG_MXC_NAND_IP_REGS_BASE   NFC_BASE_ADDR
+#define CONFIG_MXC_NAND_HWECC
+#define CONFIG_SYS_NAND_MAX_CHIPS      0x1
+#define CONFIG_SYS_MAX_NAND_DEVICE     0x1
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#ifdef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_OFFSET              CONFIG_U_BOOT_IMG_SIZE
+#define CONFIG_ENV_SIZE                        0x20000 /* 128 KiB */
+#define CONFIG_ENV_RANGE               0x60000
+#endif
+#define CONFIG_SYS_NAND_BASE           0x00000000
+#endif /* CONFIG_CMD_NAND */
+
+/*
+ * MMC Driver
+ */
+#ifdef CONFIG_CMD_MMC
+#ifndef CONFIG_ENV_IS_IN_NAND
+#endif
+#define CONFIG_SYS_FSL_ESDHC_ADDR      0
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_CMD_EXT2
+
+/*
+ * Environments on MMC
+ */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV         0
+#define CONFIG_ENV_OVERWRITE
+/* Associated with the MMC layout defined in mmcops.c */
+#define CONFIG_ENV_OFFSET              SZ_1K
+#define CONFIG_ENV_SIZE                        (SZ_128K - CONFIG_ENV_OFFSET)
+#define CONFIG_DYNAMIC_MMC_DEVNO
+#endif /* CONFIG_ENV_IS_IN_MMC */
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+#define MTDPARTS_DEFAULT               "mtdparts=" MTD_NAME ":"        \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),"                                                        \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env2),6m(linux),32m(rootfs),89344k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+#else
+#define MTDPARTS_DEFAULT               "mtdparts=" MTD_NAME ":"        \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),6m(linux),32m(rootfs),89728k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+                                       GENERATED_GBL_DATA_SIZE)
+
+#ifdef CONFIG_CMD_IIM
+#define CONFIG_FSL_IIM
+#endif
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/tx53.h b/include/configs/tx53.h
new file mode 100644 (file)
index 0000000..96d82a2
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2012-2014 <LW@KARO-electronics.de>
+ *
+ * SPDX-License-Identifier:      GPL-2.0
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+#include <asm/arch/imx-regs.h>
+
+/*
+ * Ka-Ro TX53 board - SoC configuration
+ */
+#define CONFIG_SYS_MX5_IOMUX_V3
+#define CONFIG_MXC_GPIO                        /* GPIO control */
+#define CONFIG_SYS_MX5_HCLK            24000000
+#define CONFIG_SYS_DDR_CLKSEL          0
+#define CONFIG_SYS_HZ                  1000    /* Ticks per second */
+#define CONFIG_SHOW_ACTIVITY
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_BOARD_EARLY_INIT_F
+
+/* LCD Logo and Splash screen support */
+#define CONFIG_LCD
+#ifdef CONFIG_LCD
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_VIDEO_IPUV3
+#define CONFIG_IPUV3_CLK               200000000
+#define CONFIG_LCD_LOGO
+#define LCD_BPP                                LCD_COLOR32
+#define CONFIG_CMD_BMP
+#define CONFIG_VIDEO_BMP_RLE8
+#endif /* CONFIG_LCD */
+
+/*
+ * Memory configuration options
+ */
+#ifndef CONFIG_SYS_SDRAM_SIZE
+#define CONFIG_SYS_SDRAM_SIZE          (SZ_512M * CONFIG_NR_DRAM_BANKS)
+#endif
+
+#define PHYS_SDRAM_1                   0x70000000      /* Base address of bank 1 */
+#define PHYS_SDRAM_1_SIZE              (CONFIG_SYS_SDRAM_SIZE / CONFIG_NR_DRAM_BANKS)
+#if CONFIG_NR_DRAM_BANKS > 1
+#define PHYS_SDRAM_2                   0xb0000000      /* Base address of bank 2 */
+#define PHYS_SDRAM_2_SIZE              PHYS_SDRAM_1_SIZE
+#endif
+#define CONFIG_STACKSIZE               SZ_128K
+#define CONFIG_SYS_MALLOC_LEN          SZ_8M
+#define CONFIG_SYS_MEMTEST_START       PHYS_SDRAM_1    /* Memtest start address */
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START + SZ_4M)
+#define CONFIG_SYS_SDRAM_CLK           400
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT              "TX53 U-Boot > "
+#define CONFIG_SYS_CBSIZE              2048    /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                               /* Print buffer size */
+#define CONFIG_SYS_MAXARGS             256     /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE                        /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE                   /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING                 /* Command history etc */
+
+#define CONFIG_SYS_64BIT_VSPRINTF
+
+/*
+ * Flattened Device Tree (FDT) support
+*/
+
+/*
+ * Boot Linux
+ */
+#define xstr(s)                                str(s)
+#define str(s)                         #s
+#define __pfx(x, s)                    (x##s)
+#define _pfx(x, s)                     __pfx(x, s)
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY               3
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_SYS_AUTOLOAD            "no"
+#define CONFIG_BOOTFILE                        "uImage"
+#define CONFIG_BOOTARGS                        "init=/linuxrc console=ttymxc0,115200 ro debug panic=1"
+#define CONFIG_BOOTCOMMAND             "run bootcmd_${boot_mode} bootm_cmd"
+#define CONFIG_LOADADDR                        78000000
+#define CONFIG_FDTADDR                 71000000
+#define CONFIG_SYS_LOAD_ADDR           _pfx(0x, CONFIG_LOADADDR)
+#define CONFIG_SYS_FDT_ADDR            _pfx(0x, CONFIG_FDTADDR)
+#define CONFIG_U_BOOT_IMG_SIZE         SZ_1M
+#ifndef CONFIG_SYS_LVDS_IF
+#define DEFAULT_VIDEO_MODE             "VGA"
+#else
+#define DEFAULT_VIDEO_MODE             "HSD100PXN1"
+#endif
+
+/*
+ * Extra Environment Settings
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock3 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/mmcblk0p2 rootwait\0"                               \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs"              \
+       ";nboot linux\0"                                                \
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=nand\0"                                              \
+       "cpu_clk=800\0"                                                 \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"                       \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=" DEFAULT_VIDEO_MODE "\0"
+
+#define MTD_NAME                       "mxc_nand"
+#define MTDIDS_DEFAULT                 "nand0=" MTD_NAME
+
+/*
+ * U-Boot Commands
+ */
+#include <config_cmd_default.h>
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE           UART1_BASE
+#define CONFIG_BAUDRATE                        115200          /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200, }
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/*
+ * GPIO driver
+ */
+#define CONFIG_MXC_GPIO
+
+/*
+ * Ethernet Driver
+ */
+#ifdef CONFIG_FEC_MXC
+#define IMX_FEC_BASE                   FEC_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE            MII100
+#define CONFIG_CMD_MII
+/* Add for working with "strict" DHCP server */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_DNS
+#endif
+
+/*
+ * I2C Configs
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MXC
+#define CONFIG_SYS_I2C_BASE            I2C1_BASE_ADDR
+#define CONFIG_SYS_I2C_MX6_PORT1
+#define CONFIG_SYS_I2C_SPEED           400000
+#define CONFIG_SYS_I2C_SLAVE           0x34
+#endif
+
+/*
+ * NAND flash driver
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_MXC_NAND_REGS_BASE      NFC_BASE_ADDR_AXI
+#define CONFIG_MXC_NAND_IP_REGS_BASE   NFC_BASE_ADDR
+#define CONFIG_MXC_NAND_HWECC
+#define CONFIG_SYS_NAND_MAX_CHIPS      0x1
+#define CONFIG_SYS_MAX_NAND_DEVICE     0x1
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#ifdef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_OFFSET              CONFIG_U_BOOT_IMG_SIZE
+#define CONFIG_ENV_SIZE                        0x20000 /* 128 KiB */
+#define CONFIG_ENV_RANGE               0x60000
+#endif
+#define CONFIG_SYS_NAND_BASE           0x00000000
+#endif /* CONFIG_CMD_NAND */
+
+/*
+ * MMC Driver
+ */
+#ifdef CONFIG_FSL_ESDHC
+#define CONFIG_SYS_FSL_ESDHC_ADDR      0
+
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_CMD_EXT2
+
+/*
+ * Environments on MMC
+ */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV         0
+#define CONFIG_ENV_OVERWRITE
+/* Associated with the MMC layout defined in mmcops.c */
+#define CONFIG_ENV_OFFSET              SZ_1K
+#define CONFIG_ENV_SIZE                        (SZ_128K - CONFIG_ENV_OFFSET)
+#define CONFIG_DYNAMIC_MMC_DEVNO
+#endif /* CONFIG_ENV_IS_IN_MMC */
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+#define MTDPARTS_DEFAULT               "mtdparts=" MTD_NAME ":"        \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),"                                                        \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env2),6m(linux),32m(rootfs),89344k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+#else
+#define MTDPARTS_DEFAULT               "mtdparts=" MTD_NAME ":"        \
+       "1m(u-boot),"                                                   \
+       xstr(CONFIG_ENV_RANGE)                                          \
+       "(env),6m(linux),32m(rootfs),89728k(userfs),512k@0x7f00000(dtb),512k@0x7f80000(bbt)ro"
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+                                       GENERATED_GBL_DATA_SIZE)
+
+#ifdef CONFIG_CMD_IIM
+#define CONFIG_FSL_IIM
+#endif
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/tx6.h b/include/configs/tx6.h
new file mode 100644 (file)
index 0000000..1e4af07
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2012-2015 <LW@KARO-electronics.de>
+ *
+ * SPDX-License-Identifier:      GPL-2.0
+ *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+#include <asm/arch/imx-regs.h>
+#include "mx6_common.h"
+
+/*
+ * Ka-Ro TX6 board - SoC configuration
+ */
+#define CONFIG_SYS_MX6_HCLK            24000000
+#define CONFIG_SYS_MX6_CLK32           32768
+#define CONFIG_SYS_HZ                  1000            /* Ticks per second */
+#define CONFIG_SHOW_ACTIVITY
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_DISPLAY_BOARDINFO
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_SYS_GENERIC_BOARD
+
+#ifndef CONFIG_TX6_UBOOT_MFG
+/* LCD Logo and Splash screen support */
+#define CONFIG_LCD
+#ifdef CONFIG_LCD
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_VIDEO_IPUV3
+#define CONFIG_IPUV3_CLK               (CONFIG_SYS_SDRAM_CLK * 1000000 / 2)
+#define CONFIG_LCD_LOGO
+#define LCD_BPP                                LCD_COLOR32
+#define CONFIG_CMD_BMP
+#define CONFIG_VIDEO_BMP_RLE8
+#endif /* CONFIG_LCD */
+#endif /* CONFIG_TX6_UBOOT_MFG */
+
+/*
+ * Memory configuration options
+ */
+#define CONFIG_NR_DRAM_BANKS           0x1             /* # of SDRAM banks */
+#define PHYS_SDRAM_1                   0x10000000      /* Base address of bank 1 */
+#ifdef CONFIG_SYS_SDRAM_BUS_WIDTH
+#define PHYS_SDRAM_1_WIDTH             CONFIG_SYS_SDRAM_BUS_WIDTH
+#elif defined(CONFIG_SYS_SDRAM_BUS_WIDTH_32)
+#define PHYS_SDRAM_1_WIDTH             32
+#elif defined(CONFIG_SYS_SDRAM_BUS_WIDTH_16)
+#define PHYS_SDRAM_1_WIDTH             16
+#else
+#define PHYS_SDRAM_1_WIDTH             64
+#endif
+#define PHYS_SDRAM_1_SIZE              (SZ_512M / 32 * PHYS_SDRAM_1_WIDTH)
+#ifdef CONFIG_MX6Q
+#define CONFIG_SYS_SDRAM_CLK           528
+#else
+#define CONFIG_SYS_SDRAM_CLK           400
+#endif
+#define CONFIG_STACKSIZE               SZ_128K
+#define CONFIG_SYS_MALLOC_LEN          SZ_8M
+#define CONFIG_SYS_MEMTEST_START       PHYS_SDRAM_1    /* Memtest start address */
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START + SZ_4M)
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#if defined(CONFIG_MX6Q)
+#define CONFIG_SYS_PROMPT              "TX6Q U-Boot > "
+#elif defined(CONFIG_MX6DL)
+#define CONFIG_SYS_PROMPT              "TX6DL U-Boot > "
+#elif defined(CONFIG_MX6S)
+#define CONFIG_SYS_PROMPT              "TX6S U-Boot > "
+#else
+#error Unsupported i.MX6 processor variant
+#endif
+#define CONFIG_SYS_CBSIZE              2048    /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE                                              \
+       (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+                                               /* Print buffer size */
+#define CONFIG_SYS_MAXARGS             256     /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
+                                               /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE                        /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE                   /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING                 /* Command history etc */
+
+#define CONFIG_SYS_64BIT_VSPRINTF
+
+/*
+ * Flattened Device Tree (FDT) support
+*/
+#ifdef CONFIG_OF_LIBFDT
+#ifdef CONFIG_TX6_NAND
+#endif
+#endif /* CONFIG_OF_LIBFDT */
+
+/*
+ * Boot Linux
+ */
+#define xstr(s)                                str(s)
+#define str(s)                         #s
+#define __pfx(x, s)                    (x##s)
+#define _pfx(x, s)                     __pfx(x, s)
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_INITRD_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#ifndef CONFIG_TX6_UBOOT_MFG
+#define CONFIG_BOOTDELAY               1
+#else
+#define CONFIG_BOOTDELAY               0
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+#define CONFIG_SYS_AUTOLOAD            "no"
+#ifndef CONFIG_TX6_UBOOT_MFG
+#define CONFIG_BOOTFILE                        "uImage"
+#define CONFIG_BOOTARGS                        "init=/linuxrc console=ttymxc0,115200 ro debug panic=1"
+#define CONFIG_BOOTCOMMAND             "run bootcmd_${boot_mode} bootm_cmd"
+#else
+#define CONFIG_BOOTCOMMAND             "env import " xstr(CONFIG_BOOTCMD_MFG_LOADADDR) ";run bootcmd_mfg"
+#define CONFIG_BOOTCMD_MFG_LOADADDR    10500000
+#define CONFIG_DELAY_ENVIRONMENT
+#endif /* CONFIG_TX6_UBOOT_MFG */
+#define CONFIG_LOADADDR                        18000000
+#define CONFIG_FDTADDR                 11000000
+#define CONFIG_SYS_LOAD_ADDR           _pfx(0x, CONFIG_LOADADDR)
+#define CONFIG_SYS_FDT_ADDR            _pfx(0x, CONFIG_FDTADDR)
+#ifndef CONFIG_SYS_LVDS_IF
+#define DEFAULT_VIDEO_MODE             "VGA"
+#else
+#define DEFAULT_VIDEO_MODE             "HSD100PXN1"
+#endif
+
+/*
+ * Extra Environments
+ */
+#ifndef CONFIG_TX6_UBOOT_MFG
+#ifdef CONFIG_ENV_IS_NOWHERE
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       "autostart=no\0"                                                \
+       "autoload=no\0"                                                 \
+       "bootdelay=-1\0"                                                \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"
+#else
+#define CONFIG_EXTRA_ENV_SETTINGS                                      \
+       "autostart=no\0"                                                \
+       "baseboard=stk5-v3\0"                                           \
+       "bootargs_jffs2=run default_bootargs;set bootargs ${bootargs}"  \
+       " root=/dev/mtdblock3 rootfstype=jffs2\0"                       \
+       "bootargs_mmc=run default_bootargs;set bootargs ${bootargs}"    \
+       MMC_ROOT_STR                                                    \
+       "bootargs_nfs=run default_bootargs;set bootargs ${bootargs}"    \
+       " root=/dev/nfs nfsroot=${nfs_server}:${nfsroot},nolock"        \
+       " ip=dhcp\0"                                                    \
+       "bootargs_ubifs=run default_bootargs;set bootargs ${bootargs}"  \
+       " ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs\0"           \
+       "bootcmd_jffs2=set autostart no;run bootargs_jffs2"             \
+       ";nboot linux\0"                                                \
+       "bootcmd_mmc=set autostart no;run bootargs_mmc"                 \
+       ";fatload mmc 0 ${loadaddr} uImage\0"                           \
+       CONFIG_SYS_BOOT_CMD_NAND                                        \
+       "bootcmd_net=set autoload y;set autostart n;run bootargs_nfs"   \
+       ";dhcp\0"                                                       \
+       "bootm_cmd=bootm ${loadaddr} - ${fdtaddr}\0"                    \
+       "boot_mode=" CONFIG_SYS_DEFAULT_BOOT_MODE "\0"                  \
+       "cpu_clk=800\0"                                                 \
+       "default_bootargs=set bootargs " CONFIG_BOOTARGS                \
+       " ${append_bootargs}\0"                                         \
+       "fdtaddr=" xstr(CONFIG_FDTADDR) "\0"                            \
+       CONFIG_SYS_FDTSAVE_CMD                                          \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
+       "nfsroot=/tftpboot/rootfs\0"                                    \
+       "otg_mode=device\0"                                             \
+       ROOTPART_UUID_STR                                               \
+       "touchpanel=tsc2007\0"                                          \
+       "video_mode=" DEFAULT_VIDEO_MODE "\0"
+#endif /*  CONFIG_ENV_IS_NOWHERE */
+#endif /*  CONFIG_TX6_UBOOT_MFG */
+
+#ifdef CONFIG_TX6_NAND
+#define CONFIG_SYS_DEFAULT_BOOT_MODE "nand"
+#define CONFIG_SYS_BOOT_CMD_NAND                                       \
+       "bootcmd_nand=set autostart no;run bootargs_ubifs;nboot linux\0"
+#define CONFIG_SYS_FDTSAVE_CMD                                         \
+       "fdtsave=fdt resize;nand erase.part dtb"                        \
+       ";nand write ${fdtaddr} dtb ${fdtsize}\0"
+#define MTD_NAME                       "gpmi-nand"
+#define MTDIDS_DEFAULT                 "nand0=" MTD_NAME
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+#define MMC_ROOT_STR " root=/dev/mmcblk0p2 rootwait\0"
+#define ROOTPART_UUID_STR ""
+#else
+#define CONFIG_SYS_DEFAULT_BOOT_MODE "mmc"
+#define CONFIG_SYS_BOOT_CMD_NAND ""
+#define CONFIG_SYS_FDTSAVE_CMD                                         \
+       "fdtsave=mmc open 0 1;mmc write ${fdtaddr} "                    \
+       xstr(CONFIG_SYS_DTB_BLKNO) " 80;mmc close 0 1\0"
+#define MMC_ROOT_STR " root=PARTUUID=${rootpart_uuid} rootwait\0"
+#define ROOTPART_UUID_STR "rootpart_uuid=0cc66cc0-02\0"
+#define MTD_NAME                       ""
+#define MTDIDS_DEFAULT                 ""
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+#endif
+#endif /* CONFIG_TX6_NAND */
+
+/*
+ * U-Boot Commands
+ */
+#include <config_cmd_default.h>
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE           UART1_BASE
+#define CONFIG_BAUDRATE                        115200          /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200, }
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+
+/*
+ * GPIO driver
+ */
+#define CONFIG_MXC_GPIO
+
+/*
+ * Ethernet Driver
+ */
+#ifdef CONFIG_FEC_MXC
+/* This is required for the FEC driver to work with cache enabled */
+#define CONFIG_SYS_ARM_CACHE_WRITETHROUGH
+
+#define IMX_FEC_BASE                   ENET_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE            RMII
+#endif
+
+/*
+ * I2C Configs
+ */
+#ifdef CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_BASE            I2C1_BASE_ADDR
+#define CONFIG_SYS_I2C_SPEED           400000
+#if defined(CONFIG_TX6_REV)
+#if CONFIG_TX6_REV == 0x1
+#define CONFIG_SYS_I2C_SLAVE           0x3c
+#define CONFIG_LTC3676
+#elif CONFIG_TX6_REV == 0x2
+#define CONFIG_SYS_I2C_SLAVE           0x32
+#define CONFIG_RN5T618
+#elif CONFIG_TX6_REV == 0x3
+#define CONFIG_SYS_I2C_SLAVE           0x33
+#define CONFIG_RN5T567
+#else
+#error Unsupported TX6 module revision
+#endif
+#endif /* CONFIG_TX6_REV */
+/* autodetect which PMIC is present to derive TX6_REV */
+#define CONFIG_LTC3676                 /* TX6_REV == 1 */
+#define CONFIG_RN5T567                 /* TX6_REV == 3 */
+#endif /* CONFIG_CMD_I2C */
+
+#define CONFIG_ENV_OVERWRITE
+
+/*
+ * NAND flash driver
+ */
+#ifdef CONFIG_TX6_NAND
+#define CONFIG_SYS_MXS_DMA_CHANNEL     4
+#define CONFIG_SYS_MAX_FLASH_BANKS     0x1
+#define CONFIG_SYS_NAND_MAX_CHIPS      0x1
+#define CONFIG_SYS_MAX_NAND_DEVICE     0x1
+#define CONFIG_SYS_NAND_BASE           0x00000000
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+
+#define CONFIG_ENV_OFFSET              (CONFIG_U_BOOT_IMG_SIZE + CONFIG_SYS_NAND_U_BOOT_OFFS)
+#define CONFIG_ENV_SIZE                        SZ_128K
+#define CONFIG_ENV_RANGE               (3 * CONFIG_SYS_NAND_BLOCK_SIZE)
+#else
+#undef CONFIG_ENV_IS_IN_NAND
+#endif /* CONFIG_TX6_NAND */
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+#define CONFIG_SYS_ENV_PART_STR                xstr(CONFIG_SYS_ENV_PART_SIZE)  \
+       "(env),"                                                        \
+       xstr(CONFIG_SYS_ENV_PART_SIZE)                                  \
+       "(env2),"
+#define CONFIG_SYS_USERFS_PART_STR     xstr(CONFIG_SYS_USERFS_PART_SIZE) "(userfs)"
+#else
+#define CONFIG_SYS_ENV_PART_STR                xstr(CONFIG_SYS_ENV_PART_SIZE)  \
+       "(env),"
+#define CONFIG_SYS_USERFS_PART_STR     xstr(CONFIG_SYS_USERFS_PART_SIZE2) "(userfs)"
+#endif /* CONFIG_ENV_OFFSET_REDUND */
+
+/*
+ * MMC Driver
+ */
+#ifdef CONFIG_FSL_ESDHC
+#define CONFIG_SYS_FSL_ESDHC_ADDR      0
+#endif
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+#define CONFIG_CMD_EXT2
+
+/*
+ * Environments on MMC
+ */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV         0
+#define CONFIG_SYS_MMC_ENV_PART                0x1
+#define CONFIG_DYNAMIC_MMC_DEVNO
+#endif /* CONFIG_ENV_IS_IN_MMC */
+#else
+#undef CONFIG_ENV_IS_IN_MMC
+#endif /* CONFIG_CMD_MMC */
+
+#ifdef CONFIG_ENV_IS_NOWHERE
+#undef CONFIG_ENV_SIZE
+#define CONFIG_ENV_SIZE                        SZ_4K
+#endif
+
+#ifdef CONFIG_TX6_NAND
+#define MTDPARTS_DEFAULT               "mtdparts=" MTD_NAME ":"        \
+       xstr(CONFIG_SYS_U_BOOT_PART_SIZE)                               \
+       "@" xstr(CONFIG_SYS_NAND_U_BOOT_OFFS)                           \
+       "(u-boot),"                                                     \
+       CONFIG_SYS_ENV_PART_STR                                         \
+       "6m(linux),32m(rootfs)," CONFIG_SYS_USERFS_PART_STR ","         \
+       xstr(CONFIG_SYS_DTB_PART_SIZE)                                  \
+       "@" xstr(CONFIG_SYS_NAND_DTB_OFFSET) "(dtb),"                   \
+       xstr(CONFIG_SYS_NAND_BBT_SIZE)                                  \
+       "@" xstr(CONFIG_SYS_NAND_BBT_OFFSET) "(bbt)ro"
+#else
+#define MTDPARTS_DEFAULT               ""
+#endif
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR                (CONFIG_SYS_SDRAM_BASE + 0x1000 - /* Fix this */ \
+                                       GENERATED_GBL_DATA_SIZE)
+
+#endif /* __CONFIG_H */
index c1b6648591e410e23d13a8b88aa27cdb8233efdb..29bfe28801b86ab8c0912513d99e13c6993bb241 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef  __FSL_ESDHC_H__
 #define        __FSL_ESDHC_H__
 
+#include <linux/compat.h>
 #include <asm/errno.h>
 #include <asm/byteorder.h>
 
 #define ESDHC_HOSTCAPBLT_HSS   0x00200000
 
 struct fsl_esdhc_cfg {
-       u32     esdhc_base;
+       void __iomem *esdhc_base;
        u32     sdhc_clk;
        u8      max_bus_width;
        struct mmc_config cfg;
similarity index 62%
rename from drivers/video/ipu.h
rename to include/ipu.h
index 091b58fb47bfccfa4bc30bfdd9e87006bbafa438..b1143a42703bea06da690667e9df211f10b5dc92 100644 (file)
@@ -4,68 +4,25 @@
  * (C) Copyright 2010
  * Stefano Babic, DENX Software Engineering, sbabic@denx.de
  *
- * Linux IPU driver for MX51:
+ * Linux IPU driver:
  *
- * (C) Copyright 2005-2010 Freescale Semiconductor, Inc.
+ * (C) Copyright 2005-2011 Freescale Semiconductor, Inc.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-#ifndef __ASM_ARCH_IPU_H__
-#define __ASM_ARCH_IPU_H__
+#ifndef __IPU_H__
+#define __IPU_H__
 
 #include <linux/types.h>
-#include <ipu_pixfmt.h>
+#include <linux/list.h>
+#include <linux/fb.h>
+
+struct clk;
 
 #define IDMA_CHAN_INVALID      0xFF
 #define HIGH_RESOLUTION_WIDTH  1024
 
-struct clk {
-       const char *name;
-       int id;
-       /* Source clock this clk depends on */
-       struct clk *parent;
-       /* Secondary clock to enable/disable with this clock */
-       struct clk *secondary;
-       /* Current clock rate */
-       unsigned long rate;
-       /* Reference count of clock enable/disable */
-       __s8 usecount;
-       /* Register bit position for clock's enable/disable control. */
-       u8 enable_shift;
-       /* Register address for clock's enable/disable control. */
-       void *enable_reg;
-       u32 flags;
-       /*
-        * Function ptr to recalculate the clock's rate based on parent
-        * clock's rate
-        */
-       void (*recalc) (struct clk *);
-       /*
-        * Function ptr to set the clock to a new rate. The rate must match a
-        * supported rate returned from round_rate. Leave blank if clock is not
-       * programmable
-        */
-       int (*set_rate) (struct clk *, unsigned long);
-       /*
-        * Function ptr to round the requested clock rate to the nearest
-        * supported rate that is less than or equal to the requested rate.
-        */
-       unsigned long (*round_rate) (struct clk *, unsigned long);
-       /*
-        * Function ptr to enable the clock. Leave blank if clock can not
-        * be gated.
-        */
-       int (*enable) (struct clk *);
-       /*
-        * Function ptr to disable the clock. Leave blank if clock can not
-        * be gated.
-        */
-       void (*disable) (struct clk *);
-       /* Function ptr to set the parent clock of the clock. */
-       int (*set_parent) (struct clk *, struct clk *);
-};
-
 /*
  * Enumeration of Synchronous (Memory-less) panel types
  */
@@ -74,6 +31,51 @@ typedef enum {
        IPU_PANEL_TFT,
 } ipu_panel_t;
 
+/*  IPU Pixel format definitions */
+#define fourcc(a, b, c, d)\
+       (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+/*
+ * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
+ * the same used by V4L2 API.
+ */
+
+#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0')
+#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1')
+#define IPU_PIX_FMT_LVDS666 fourcc('L', 'V', 'D', '6')
+#define IPU_PIX_FMT_LVDS888 fourcc('L', 'V', 'D', '8')
+
+#define IPU_PIX_FMT_RGB332  fourcc('R', 'G', 'B', '1') /*<  8  RGB-3-3-2    */
+#define IPU_PIX_FMT_RGB555  fourcc('R', 'G', 'B', 'O') /*< 16  RGB-5-5-5    */
+#define IPU_PIX_FMT_RGB565  fourcc('R', 'G', 'B', 'P') /*< 1 6  RGB-5-6-5   */
+#define IPU_PIX_FMT_RGB666  fourcc('R', 'G', 'B', '6') /*< 18  RGB-6-6-6    */
+#define IPU_PIX_FMT_BGR666  fourcc('B', 'G', 'R', '6') /*< 18  BGR-6-6-6    */
+#define IPU_PIX_FMT_BGR24   fourcc('B', 'G', 'R', '3') /*< 24  BGR-8-8-8    */
+#define IPU_PIX_FMT_RGB24   fourcc('R', 'G', 'B', '3') /*< 24  RGB-8-8-8    */
+#define IPU_PIX_FMT_BGR32   fourcc('B', 'G', 'R', '4') /*< 32  BGR-8-8-8-8  */
+#define IPU_PIX_FMT_BGRA32  fourcc('B', 'G', 'R', 'A') /*< 32  BGR-8-8-8-8  */
+#define IPU_PIX_FMT_RGB32   fourcc('R', 'G', 'B', '4') /*< 32  RGB-8-8-8-8  */
+#define IPU_PIX_FMT_RGBA32  fourcc('R', 'G', 'B', 'A') /*< 32  RGB-8-8-8-8  */
+#define IPU_PIX_FMT_ABGR32  fourcc('A', 'B', 'G', 'R') /*< 32  ABGR-8-8-8-8 */
+
+/* YUV Interleaved Formats */
+#define IPU_PIX_FMT_YUYV    fourcc('Y', 'U', 'Y', 'V') /*< 16 YUV 4:2:2 */
+#define IPU_PIX_FMT_UYVY    fourcc('U', 'Y', 'V', 'Y') /*< 16 YUV 4:2:2 */
+#define IPU_PIX_FMT_Y41P    fourcc('Y', '4', '1', 'P') /*< 12 YUV 4:1:1 */
+#define IPU_PIX_FMT_YUV444  fourcc('Y', '4', '4', '4') /*< 24 YUV 4:4:4 */
+
+/* two planes -- one Y, one Cb + Cr interleaved  */
+#define IPU_PIX_FMT_NV12    fourcc('N', 'V', '1', '2') /* 12  Y/CbCr 4:2:0  */
+
+#define IPU_PIX_FMT_GREY    fourcc('G', 'R', 'E', 'Y') /*< 8  Greyscale */
+#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*< 9  YVU 4:1:0 */
+#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*< 9  YUV 4:1:0 */
+#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*< 12 YVU 4:2:0 */
+#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*< 12 YUV 4:2:0 */
+#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2')        /*< 12 YUV 4:2:0 */
+#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*< 16 YVU 4:2:2 */
+#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*< 16 YUV 4:2:2 */
+
 /*
  * IPU Driver channels definitions.
  * Note these are different from IDMA channels
@@ -119,14 +121,25 @@ typedef enum {
  * Enumeration of types of buffers for a logical channel.
  */
 typedef enum {
-       IPU_OUTPUT_BUFFER = 0,  /*< Buffer for output from IPU */
-       IPU_ALPHA_IN_BUFFER = 1,        /*< Buffer for input to IPU */
-       IPU_GRAPH_IN_BUFFER = 2,        /*< Buffer for input to IPU */
-       IPU_VIDEO_IN_BUFFER = 3,        /*< Buffer for input to IPU */
+       IPU_OUTPUT_BUFFER = 0,          /* Buffer for output from IPU */
+       IPU_ALPHA_IN_BUFFER = 1,        /* Buffer for input to IPU */
+       IPU_GRAPH_IN_BUFFER = 2,        /* Buffer for input to IPU */
+       IPU_VIDEO_IN_BUFFER = 3,        /* Buffer for input to IPU */
        IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
        IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
 } ipu_buffer_t;
 
+
+/*
+ * Enumeration of version of IPU V3 .
+ */
+typedef enum {
+       IPUV3_HW_REV_IPUV3DEX = 2,      /* IPUv3D, IPUv3E  IPUv3EX  */
+       IPUV3_HW_REV_IPUV3M = 3,        /* IPUv3M */
+       IPUV3_HW_REV_IPUV3H = 4,        /* IPUv3H */
+} ipu3_hw_rev_t;
+
+
 #define IPU_PANEL_SERIAL               1
 #define IPU_PANEL_PARALLEL             2
 
@@ -206,7 +219,19 @@ typedef enum {
        YUV
 } ipu_color_space_t;
 
+typedef enum {
+       DI_PCLK_PLL3,
+       DI_PCLK_LDB,
+       DI_PCLK_TVE
+} ipu_di_clk_parent_t;
+
 /* Common IPU API */
+int ipuv3_fb_init(struct fb_videomode *mode, int di,
+               unsigned int interface_pix_fmt,
+               ipu_di_clk_parent_t di_clk_parent,
+               unsigned long di_clk_val, int bpp);
+void ipuv3_fb_shutdown(void);
+
 int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params);
 void ipu_uninit_channel(ipu_channel_t channel);
 
@@ -242,7 +267,7 @@ int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
 
 uint32_t bytes_per_pixel(uint32_t fmt);
 
-void clk_enable(struct clk *clk);
+int clk_enable(struct clk *clk);
 void clk_disable(struct clk *clk);
 u32 clk_get_rate(struct clk *clk);
 int clk_set_rate(struct clk *clk, unsigned long rate);
@@ -252,7 +277,7 @@ int clk_get_usecount(struct clk *clk);
 struct clk *clk_get_parent(struct clk *clk);
 
 void ipu_dump_registers(void);
-int ipu_probe(void);
+int ipu_probe(int di, ipu_di_clk_parent_t di_clk_parent, int di_clk_val);
 
 void ipu_dmfc_init(int dmfc_type, int first);
 void ipu_init_dc_mappings(void);
@@ -266,4 +291,4 @@ void ipu_dp_uninit(ipu_channel_t channel);
 void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap);
 ipu_color_space_t format_to_colorspace(uint32_t fmt);
 
-#endif
+#endif /* __IPU_H */
index 160f940d2a6698f6538e084a4322679d69855ae0..eb1d12871fced64adbd09991f8324a369c15a7db 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * Copyright (C) 2004-2010 Freescale Semiconductor, Inc.
+ *
  * MPC823 and PXA LCD Controller
  *
  * Modeled after video interface by Paolo Scaffardi
@@ -257,6 +259,9 @@ extern vidinfo_t panel_info;
 
 /* Video functions */
 
+void   lcd_disable(void);
+void   lcd_panel_disable(void);
+
 void   lcd_putc(const char c);
 void   lcd_puts(const char *s);
 void   lcd_printf(const char *fmt, ...);
@@ -404,14 +409,23 @@ void lcd_sync(void);
 # define CONSOLE_COLOR_WHITE   0x00ffffff      /* Must remain last / highest*/
 # define NBYTES(bit_code)      (NBITS(bit_code) >> 3)
 
-#else
+#elif LCD_BPP == LCD_COLOR16
 
 /*
  * 16bpp color definitions
  */
 # define CONSOLE_COLOR_BLACK   0x0000
+# define CONSOLE_COLOR_RED     0xf800
+# define CONSOLE_COLOR_GREEN   0x07e0
+# define CONSOLE_COLOR_YELLOW  0xffe0
+# define CONSOLE_COLOR_BLUE    0x001f
+# define CONSOLE_COLOR_MAGENTA 0xf81f
+# define CONSOLE_COLOR_CYAN    0x07ff
+# define CONSOLE_COLOR_GREY    0xcccc
 # define CONSOLE_COLOR_WHITE   0xffff  /* Must remain last / highest   */
 
+#else
+#error Invalid LCD_BPP setting
 #endif /* color definitions */
 
 /************************************************************************/
similarity index 100%
rename from drivers/video/mxcfb.h
rename to include/mxcfb.h
index 15e31ab538ba5e84c09ae512b7f5a2dad0c21c47..3c8dea5f8709a23ee5ce4a4bc1fcebd26626bb08 100644 (file)
 
 #include <config.h>
 
-/*
- * All boards using a given driver must convert to self-init
- * at the same time, so do it here.  When all drivers are
- * converted, this will go away.
- */
-#ifdef CONFIG_SPL_BUILD
-#if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_FSL_IFC)
-#define CONFIG_SYS_NAND_SELF_INIT
-#endif
-#else
-#if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_ATMEL)\
-       || defined(CONFIG_NAND_FSL_IFC)
-#define CONFIG_SYS_NAND_SELF_INIT
-#endif
-#endif
-
 extern void nand_init(void);
 
 #include <linux/compat.h>
index 73ea88b42d7defb35ddea2da2d0ff30684c26b30..0b338ff4e63c9cff6b266a4fd9617d4fbf523efd 100644 (file)
@@ -420,7 +420,7 @@ extern int          NetRestartWrap;         /* Tried all network devices */
 
 enum proto_t {
        BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
-       TFTPSRV, TFTPPUT, LINKLOCAL
+       TFTPSRV, TFTPPUT, LINKLOCAL, BOOTME
 };
 
 /* from net/net.c */
@@ -586,6 +586,9 @@ static inline void eth_set_last_protocol(int protocol)
        net_loop_last_protocol = protocol;
 #endif
 }
+#ifdef CONFIG_CMD_BOOTCE
+void BootmeStart(void);
+#endif
 
 /*
  * Check if autoload is enabled. If so, use either NFS or TFTP to download
index daffc1222d60afba54d8ad9dc5dba7d84d284fe0..c67b0646e4f29aa850d5b8f28eebc73e3f2d90d4 100644 (file)
@@ -217,4 +217,40 @@ int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
 int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int));
 #endif
 
+#ifdef CONFIG_DRIVER_TI_CPSW
+enum {
+       CPSW_CTRL_VERSION_1 = 0, /* version1 devices */
+       CPSW_CTRL_VERSION_2      /* version2 devices */
+};
+
+struct cpsw_slave_data {
+       u32             slave_reg_ofs;
+       u32             sliver_reg_ofs;
+       int             phy_id;
+       int             phy_if;
+};
+
+struct cpsw_platform_data {
+       u32     mdio_base;
+       u32     cpsw_base;
+       int     mdio_div;
+       int     channels;       /* number of cpdma channels (symmetric) */
+       u32     cpdma_reg_ofs;  /* cpdma register offset                */
+       int     slaves;         /* number of slave cpgmac ports         */
+       u32     ale_reg_ofs;    /* address lookup engine reg offset     */
+       int     ale_entries;    /* ale table size                       */
+       u32     host_port_reg_ofs;      /* cpdma host port registers    */
+       u32     hw_stats_reg_ofs;       /* cpsw hw stats counters       */
+       u32     mac_control;
+       struct cpsw_slave_data  *slave_data;
+       void    (*control)(int enabled);
+       void    (*phy_init)(char *name, int addr);
+       u32     gigabit_en;     /* gigabit capable AND enabled          */
+       u32     host_port_num;
+       u8      version;
+};
+
+int cpsw_register(struct cpsw_platform_data *data);
+#endif /* CONFIG_DRIVER_TI_CPSW */
+
 #endif /* _NETDEV_H_ */
index b2e5bf726f2b60d7d81d8bafb5a9ec8357749ff4..36e301ade41c33b1dfab7e721844aae869270a14 100644 (file)
@@ -43,7 +43,7 @@ int spl_start_uboot(void);
 void spl_display_print(void);
 
 /* NAND SPL functions */
-void spl_nand_load_image(void);
+int spl_nand_load_image(void);
 
 /* OneNAND SPL functions */
 void spl_onenand_load_image(void);
diff --git a/include/wince.h b/include/wince.h
new file mode 100644 (file)
index 0000000..68f480d
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __WINCE_H__
+#define __WINCE_H__
+
+/* Bin image parse results */
+#define CE_PR_EOF      0
+#define CE_PR_MORE     1
+#define CE_PR_ERROR    2
+
+#pragma pack(1)
+
+/* Edbg BOOTME packet structures */
+typedef struct {
+       unsigned int    id;             /* Protocol identifier ("EDBG" on the wire) */
+       unsigned char   service;        /* Service identifier */
+       unsigned char   flags;          /* Flags (see defs below) */
+       unsigned char   seqNum;         /* For detection of dropped packets */
+       unsigned char   cmd;            /* For administrative messages */
+       uchar           data[];         /* Cmd specific data starts here (format is determined by
+                                        * Cmd, len is determined by UDP packet size)
+                                        */
+} eth_dbg_hdr;
+
+#define OFFSETOF(s,m)                                  ((unsigned int)&(((s*)0)->m))
+#define EDBG_DATA_OFFSET                               (OFFSETOF(eth_dbg_hdr, data))
+
+typedef struct {
+       unsigned char   versionMajor;   /* Bootloader version */
+       unsigned char   versionMinor;   /* Bootloader version */
+       unsigned char   macAddr[6];     /* Ether address of device (net byte order) */
+       unsigned int    ipAddr;         /* IP address of device (net byte order) */
+       char            platformId[17]; /* Platform Id string (NULL terminated) */
+       char            deviceName[17]; /* Device name string (NULL terminated). Should include
+                                        * platform and number based on Ether address
+                                        * (e.g. Odo42, CEPCLS2346, etc)
+                                        */
+       unsigned char   cpuId;          /* CPU identifier (upper nibble = type) */
+/* The following fields were added in CE 3.0 Platform Builder release */
+       unsigned char   bootmeVer;      /* BOOTME Version.
+                                        * Must be in the range 2 -> EDBG_CURRENT_BOOTME_VERSION,
+                                        * or remaining fields will be ignored by Eshell and defaults will be used.
+                                        */
+       unsigned int    bootFlags;      /* Boot Flags */
+       unsigned short  downloadPort;   /* Download Port (net byte order) (0 -> EDBG_DOWNLOAD_PORT) */
+       unsigned short  svcPort;        /* Service Port (net byte order) (0 -> EDBG_SVC_PORT) */
+} edbg_bootme_data;
+
+#define BOOTME_PKT_SIZE                        (EDBG_DATA_OFFSET + sizeof(edbg_bootme_data))
+
+// WinCE .BIN file format signature
+#define CE_BIN_SIGN    "B000FF\x0A"
+#define CE_BIN_SIGN_LEN        7
+
+typedef struct {
+       unsigned char sign[CE_BIN_SIGN_LEN];
+       unsigned int rtiPhysAddr;
+       unsigned int rtiPhysLen;
+} ce_bin_hdr;
+
+typedef struct {
+       unsigned int physAddr;
+       unsigned int physLen;
+       unsigned int chkSum;
+       unsigned char data[];
+} ce_bin_entry;
+
+// CE ROM image structures
+
+#define ROM_SIGNATURE_OFFSET           0x40    /* Offset from the image's physfirst address to the ROM signature. */
+#define ROM_SIGNATURE                  0x43454345 /* Signature 'CECE' (little endian) */
+#define ROM_TOC_POINTER_OFFSET         0x44    /* Offset from the image's physfirst address to the TOC pointer. */
+#define ROM_TOC_OFFSET_OFFSET          0x48    /* Offset from the image's physfirst address to the TOC offset (from physfirst). */
+
+typedef struct {
+       unsigned int    dllfirst;       /* first DLL address */
+       unsigned int    dlllast;        /* last DLL address */
+       unsigned int    physfirst;      /* first physical address */
+       unsigned int    physlast;       /* highest physical address */
+       unsigned int    nummods;        /* number of TOCentry's */
+       unsigned int    ramStart;       /* start of RAM */
+       unsigned int    ramFree;        /* start of RAM free space */
+       unsigned int    ramEnd;         /* end of RAM */
+       unsigned int    copyEntries;    /* number of copy section entries */
+       unsigned int    copyOffset;     /* offset to copy section */
+       unsigned int    profileLen;     /* length of PROFentries RAM */
+       unsigned int    profileOffset;  /* offset to PROFentries */
+       unsigned int    numfiles;       /* number of FILES */
+       unsigned int    kernelFlags;    /* optional kernel flags from ROMFLAGS .bib config option */
+       unsigned int    fsRamPercent;   /* Percentage of RAM used for filesystem */
+/* from FSRAMPERCENT .bib config option
+ * byte 0 = #4K chunks/Mbyte of RAM for filesystem 0-2Mbytes 0-255
+ * byte 1 = #4K chunks/Mbyte of RAM for filesystem 2-4Mbytes 0-255
+ * byte 2 = #4K chunks/Mbyte of RAM for filesystem 4-6Mbytes 0-255
+ * byte 3 = #4K chunks/Mbyte of RAM for filesystem > 6Mbytes 0-255
+ */
+       unsigned int    drivglobStart;  /* device driver global starting address */
+       unsigned int    drivglobLen;    /* device driver global length */
+       unsigned short  cpuType;        /* CPU (machine) Type */
+       unsigned short  miscFlags;      /* Miscellaneous flags */
+       void            *extensions;    /* pointer to ROM Header extensions */
+       unsigned int    trackingStart;  /* tracking memory starting address */
+       unsigned int    trackingLen;    /* tracking memory ending address */
+} ce_rom_hdr;
+
+/* Win32 FILETIME strcuture */
+typedef struct {
+    unsigned int       loDateTime;
+    unsigned int       hiDateTime;
+} ce_file_time;
+
+/* Table Of Contents entry structure */
+typedef struct {
+       unsigned int    fileAttributes;
+       ce_file_time    fileTime;
+       unsigned int    fileSize;
+       char            *fileName;
+       unsigned int    e32Offset;            /* Offset to E32 structure */
+       unsigned int    o32Offset;            /* Offset to O32 structure */
+       unsigned int    loadOffset;           /* MODULE load buffer offset */
+} ce_toc_entry;
+
+/* Extra information header block */
+typedef struct {
+       unsigned int    rva;            /* Virtual relative address of info    */
+       unsigned int    size;           /* Size of information block           */
+} e32_info;
+
+#define ROM_EXTRA      9
+
+typedef struct {
+       unsigned short  e32_objcnt;     /* Number of memory objects            */
+       unsigned short  e32_imageflags; /* Image flags                         */
+       unsigned int    e32_entryrva;   /* Relative virt. addr. of entry point */
+       unsigned int    e32_vbase;      /* Virtual base address of module      */
+       unsigned short  e32_subsysmajor;/* The subsystem major version number  */
+       unsigned short  e32_subsysminor;/* The subsystem minor version number  */
+       unsigned int    e32_stackmax;   /* Maximum stack size                  */
+       unsigned int    e32_vsize;      /* Virtual size of the entire image    */
+       unsigned int    e32_sect14rva;  /* section 14 rva */
+       unsigned int    e32_sect14size; /* section 14 size */
+       unsigned int    e32_timestamp;  /* Time EXE/DLL was created/modified   */
+       e32_info        e32_unit[ROM_EXTRA]; /* Array of extra info units      */
+       unsigned short  e32_subsys;     /* The subsystem type                  */
+} e32_rom;
+
+/* OS config msg */
+
+#define EDBG_FL_DBGMSG    0x01  /* Debug messages */
+#define EDBG_FL_PPSH      0x02  /* Text shell */
+#define EDBG_FL_KDBG      0x04  /* Kernel debugger */
+#define EDBG_FL_CLEANBOOT 0x08  /* Force a clean boot */
+
+typedef struct {
+       unsigned char   flags;           /* Flags that will be used to determine what features are
+                                         * enabled over ethernet (saved in driver globals by bootloader)
+                                         */
+       unsigned char   kitlTransport;   /* Tells KITL which transport to start */
+
+       /* The following specify addressing info, only valid if the corresponding
+        * flag is set in the Flags field.
+        */
+       unsigned int    dbgMsgIPAddr;
+       unsigned short  dbgMsgPort;
+       unsigned int    ppshIPAddr;
+       unsigned short  ppshPort;
+       unsigned int    kdbgIPAddr;
+       unsigned short  kdbgPort;
+} edbg_os_config_data;
+
+/* Driver globals structure
+ * Used to pass driver globals info from RedBoot to WinCE core
+ */
+#define DRV_GLB_SIGNATURE      0x424C4744      /* "DGLB" */
+#define STD_DRV_GLB_SIGNATURE  0x53475241      /* "ARGS" */
+
+typedef struct {
+       unsigned int    signature;              /* Signature */
+       unsigned int    flags;                  /* Misc flags */
+       unsigned int    ipAddr;                 /* IP address of device (net byte order) */
+       unsigned int    ipGate;                 /* IP address of gateway (net byte order) */
+       unsigned int    ipMask;                 /* Subnet mask */
+       unsigned char   macAddr[6];             /* Ether address of device (net byte order) */
+       edbg_os_config_data edbgConfig;         /* EDBG services info */
+} ce_driver_globals;
+
+#pragma pack(4)
+
+typedef struct
+{
+       unsigned long   signature;
+       unsigned short  oalVersion;
+       unsigned short  bspVersion;
+} OAL_ARGS_HEADER;
+
+typedef struct _DEVICE_LOCATION
+{
+       unsigned long IfcType;
+       unsigned long BusNumber;
+       unsigned long LogicalLoc;
+       void *PhysicalLoc;
+       unsigned long Pin;
+} DEVICE_LOCATION;
+
+typedef struct
+{
+       unsigned long flags;
+       DEVICE_LOCATION devLoc;
+       union {
+               struct {
+                       unsigned long baudRate;
+                       unsigned long dataBits;
+                       unsigned long stopBits;
+                       unsigned long parity;
+               };
+               struct {
+                       unsigned short mac[3];
+                       unsigned long ipAddress;
+                       unsigned long ipMask;
+                       unsigned long ipRoute;
+               };
+       };
+} OAL_KITL_ARGS;
+
+typedef struct
+{
+       OAL_ARGS_HEADER header;
+       char            deviceId[16];   // Device identification
+       OAL_KITL_ARGS   kitl;
+       char            mtdparts[];
+} ce_std_driver_globals;
+
+typedef struct {
+       void         *rtiPhysAddr;
+       unsigned int rtiPhysLen;
+       void         *ePhysAddr;
+       unsigned int ePhysLen;
+       unsigned int eChkSum;
+
+       void         *eEntryPoint;
+       void         *eRamStart;
+       unsigned int eRamLen;
+
+       unsigned char parseState;
+       unsigned int parseChkSum;
+       int parseLen;
+       unsigned char *parsePtr;
+       int section;
+
+       int dataLen;
+       unsigned char *data;
+
+       int binLen;
+       int endOfBin;
+
+       edbg_os_config_data edbgConfig;
+} ce_bin;
+
+/* IPv4 support */
+
+/* Socket/connection information */
+struct sockaddr_in {
+       IPaddr_t sin_addr;
+       unsigned short sin_port;
+       unsigned short sin_family;
+       short          sin_len;
+};
+
+#define AF_INET                1
+#define INADDR_ANY     0
+#ifndef ETH_ALEN
+#define ETH_ALEN       6
+#endif
+
+enum bootme_state {
+       BOOTME_INIT,
+       BOOTME_DOWNLOAD,
+       BOOTME_DEBUG_INIT,
+       BOOTME_DEBUG,
+       BOOTME_DONE,
+       BOOTME_ERROR,
+};
+
+typedef struct {
+       int verbose;
+       int link;
+#ifdef BORKED
+       struct sockaddr_in locAddr;
+       struct sockaddr_in srvAddrSend;
+       struct sockaddr_in srvAddrRecv;
+#else
+       IPaddr_t server_ip;
+#endif
+       int gotJumpingRequest;
+       int dataLen;
+//     int align_offset;
+//     int got_packet_4me;
+//     int status;
+       enum bootme_state state;
+       unsigned short blockNum;
+       unsigned char seqNum;
+       unsigned char pad;
+#if 0
+       unsigned char data[PKTSIZE_ALIGN];
+#else
+       unsigned char *data;
+#endif
+} ce_net;
+
+struct timeval {
+       long    tv_sec;         /* seconds */
+       long    tv_usec;        /* and microseconds */
+};
+
+/* Default UDP ports used for Ethernet download and EDBG messages.  May be overriden
+ * by device in BOOTME message.
+ */
+#define  EDBG_DOWNLOAD_PORT                            980   /* For downloading images to bootloader via TFTP */
+#define  EDBG_SVC_PORT                                 981   /* Other types of transfers */
+
+/* Byte string for Id field (note - must not conflict with valid TFTP
+ * opcodes (0-5), as we share the download port with TFTP)
+ */
+#define EDBG_ID                                                        0x47424445 /* "EDBG" */
+
+/* Defs for reserved values of the Service field */
+#define EDBG_SVC_DBGMSG                0   /* Debug messages */
+#define EDBG_SVC_PPSH          1   /* Text shell and PPFS file system */
+#define EDBG_SVC_KDBG          2   /* Kernel debugger */
+#define EDBG_SVC_ADMIN         0xFF  /* Administrative messages */
+
+/* Commands */
+#define EDBG_CMD_READ_REQ      1       /* Read request */
+#define EDBG_CMD_WRITE_REQ     2       /* Write request */
+#define EDBG_CMD_WRITE         3       /* Host ack */
+#define EDBG_CMD_WRITE_ACK     4       /* Target ack */
+#define EDBG_CMD_ERROR         5       /* Error */
+
+/* Service Ids from 3-FE are used for user apps */
+#define NUM_DFLT_EDBG_SERVICES 3
+
+/* Size of send and receive windows (except for stop and wait mode) */
+#define EDBG_WINDOW_SIZE       8
+
+/* The window size can be negotiated up to this amount if a client provides
+* enough memory.
+ */
+#define EDBG_MAX_WINDOW_SIZE   16
+
+/* Max size for an EDBG frame.  Based on ethernet MTU - protocol overhead.
+* Limited to one MTU because we don't do IP fragmentation on device.
+ */
+#define EDBG_MAX_DATA_SIZE     1446
+
+/* Defs for Flags field. */
+#define EDBG_FL_FROM_DEV       0x01   /* Set if message is from the device */
+#define EDBG_FL_NACK           0x02   /* Set if frame is a nack */
+#define EDBG_FL_ACK                    0x04   /* Set if frame is an ack */
+#define EDBG_FL_SYNC           0x08   /* Can be used to reset sequence # to 0 */
+#define EDBG_FL_ADMIN_RESP     0x10    /* For admin messages, indicate whether this is a response */
+
+/* Definitions for Cmd field (used for administrative messages) */
+/* Msgs from device */
+#define EDBG_CMD_BOOTME                0   /* Initial bootup message from device */
+
+/* Msgs from PC */
+#define EDBG_CMD_SETDEBUG      1       /* Used to set debug zones on device (TBD) */
+#define EDBG_CMD_JUMPIMG       2       /* Command to tell bootloader to jump to existing
+                                        * flash or RAM image. Data is same as CMD_OS_CONFIG. */
+#define EDBG_CMD_OS_CONFIG     3       /* Configure OS for debug ethernet services */
+#define EDBG_CMD_QUERYINFO     4       /* "Ping" device, and return information (same fmt as bootme) */
+#define EDBG_CMD_RESET         5       /* Command to have platform perform SW reset (e.g. so it
+                                        * can be reprogrammed).  Support for this command is
+                                        * processor dependant, and may not be implemented
+                                        * on all platforms (requires HW mods for Odo).
+                                        */
+/* Msgs from device or PC */
+#define EDBG_CMD_SVC_CONFIG    6
+#define EDBG_CMD_SVC_DATA      7
+
+#define EDBG_CMD_DEBUGBREAK    8 /* Break into debugger */
+
+/* Structures for Data portion of EDBG packets */
+#define EDBG_MAX_DEV_NAMELEN   16
+
+/* BOOTME message - Devices broadcast this message when booted to request configuration */
+#define EDBG_CURRENT_BOOTME_VERSION    2
+
+/*
+ * Capability and boot Flags for dwBootFlags in EDBG_BOOTME_DATA
+ * LOWORD for boot flags, HIWORD for capability flags
+ */
+
+/* Always download image */
+#define EDBG_BOOTFLAG_FORCE_DOWNLOAD   0x00000001
+
+/* Support passive-kitl */
+#define EDBG_CAPS_PASSIVEKITL          0x00010000
+
+/* Defs for CPUId */
+#define EDBG_CPU_TYPE_SHX                              0x10
+#define EDBG_CPU_TYPE_MIPS                             0x20
+#define EDBG_CPU_TYPE_X86                              0x30
+#define EDBG_CPU_TYPE_ARM                              0x40
+#define EDBG_CPU_TYPE_PPC                              0x50
+#define EDBG_CPU_TYPE_THUMB                            0x60
+
+#define EDBG_CPU_SH3                                   (EDBG_CPU_TYPE_SHX  | 0)
+#define EDBG_CPU_SH4                                   (EDBG_CPU_TYPE_SHX  | 1)
+#define EDBG_CPU_R3000                                 (EDBG_CPU_TYPE_MIPS | 0)
+#define EDBG_CPU_R4101                                 (EDBG_CPU_TYPE_MIPS | 1)
+#define EDBG_CPU_R4102                                 (EDBG_CPU_TYPE_MIPS | 2)
+#define EDBG_CPU_R4111                                 (EDBG_CPU_TYPE_MIPS | 3)
+#define EDBG_CPU_R4200                                 (EDBG_CPU_TYPE_MIPS | 4)
+#define EDBG_CPU_R4300                                 (EDBG_CPU_TYPE_MIPS | 5)
+#define EDBG_CPU_R5230                                 (EDBG_CPU_TYPE_MIPS | 6)
+#define EDBG_CPU_R5432                                 (EDBG_CPU_TYPE_MIPS | 7)
+#define EDBG_CPU_i486                                  (EDBG_CPU_TYPE_X86  | 0)
+#define EDBG_CPU_SA1100                                        (EDBG_CPU_TYPE_ARM | 0)
+#define EDBG_CPU_ARM720                                        (EDBG_CPU_TYPE_ARM | 1)
+#define EDBG_CPU_PPC821                                        (EDBG_CPU_TYPE_PPC | 0)
+#define EDBG_CPU_PPC403                                        (EDBG_CPU_TYPE_PPC | 1)
+#define EDBG_CPU_THUMB720                              (EDBG_CPU_TYPE_THUMB | 0)
+
+typedef enum bootme_state bootme_hand_f(const void *pkt, size_t len);
+
+int bootme_recv_frame(void *buf, size_t len, int timeout);
+int bootme_send_frame(const void *buf, size_t len);
+//void bootme_init(IPaddr_t server_ip);
+int BootMeRequest(IPaddr_t server_ip, const void *buf, size_t len, int timeout);
+//int ce_download_handler(const void *buf, size_t len);
+int BootMeDownload(bootme_hand_f *pkt_handler);
+int BootMeDebugStart(bootme_hand_f *pkt_handler);
+#endif
index e9cc8ada96a783ae18444c9f68a107bede6e0054..6ba8f7575e2132729d5784ebb7cbbdc919fd5b90 100644 (file)
@@ -9,6 +9,7 @@
 
 obj-y += checksum.o
 obj-$(CONFIG_CMD_NET)  += arp.o
+obj-$(CONFIG_CMD_BOOTCE) += bootme.o
 obj-$(CONFIG_CMD_NET)  += bootp.o
 obj-$(CONFIG_CMD_CDP)  += cdp.o
 obj-$(CONFIG_CMD_DNS)  += dns.o
diff --git a/net/bootme.c b/net/bootme.c
new file mode 100644 (file)
index 0000000..4487272
--- /dev/null
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ * based on: code from RedBoot (C) Uwe Steinkohl <US@KARO-electronics.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <wince.h>
+#include <asm/errno.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static enum bootme_state bootme_state;
+static int bootme_src_port = 0xdeadface;
+static int bootme_dst_port = 0xdeadbeef;
+static uchar bootme_ether[ETH_ALEN];
+static IPaddr_t bootme_ip;
+static int bootme_timed_out;
+static const char *output_packet; /* used by first send udp */
+static int output_packet_len;
+static unsigned long bootme_timeout;
+static bootme_hand_f *bootme_packet_handler;
+
+#ifdef DEBUG
+static void __attribute__((unused)) ce_dump_block(const void *ptr, int length)
+{
+       const char *p = ptr;
+       int i;
+       int j;
+
+       for (i = 0; i < length; i++) {
+               if (!(i % 16)) {
+                       printf("\n%p: ", ptr + i);
+               }
+
+               printf("%02x ", p[i]);
+               if (!((i + 1) % 16)){
+                       printf("      ");
+                       for (j = i - 15; j <= i; j++){
+                               if((p[j] > 0x1f) && (p[j] < 0x7f)) {
+                                       printf("%c", p[j]);
+                               } else {
+                                       printf(".");
+                               }
+                       }
+               }
+       }
+       printf("\n");
+}
+#else
+static inline void ce_dump_block(void *ptr, int length)
+{
+}
+#endif
+
+static void bootme_timeout_handler(void)
+{
+       printf("%s\n", __func__);
+       net_set_state(NETLOOP_SUCCESS);
+       bootme_timed_out++;
+}
+
+static inline int env_changed(int *id)
+{
+       int env_id = get_env_id();
+
+       if (*id != env_id) {
+               debug("env_id: %d -> %d\n", *id, env_id);
+               *id = env_id;
+               return 1;
+       }
+       return 0;
+}
+
+static int env_id;
+
+static int is_broadcast(IPaddr_t ip)
+{
+       static IPaddr_t netmask;
+       static IPaddr_t our_ip;
+
+       return (ip == ~0 ||                             /* 255.255.255.255 */
+           ((netmask & our_ip) == (netmask & ip) &&    /* on the same net */
+           (netmask | ip) == ~0));             /* broadcast to our net */
+}
+
+static int check_net_config(void)
+{
+       if (env_changed(&env_id)) {
+               char *p;
+               char *bip;
+
+               bootme_dst_port = EDBG_DOWNLOAD_PORT;
+               if (bootme_ip == 0) {
+                       bip = getenv("bootmeip");
+                       if (bip) {
+                               bootme_ip = getenv_IPaddr("bootmeip");
+                               if (!bootme_ip)
+                                       return -EINVAL;
+                               p = strchr(bip, ':');
+                               if (p) {
+                                       bootme_dst_port = simple_strtoul(p + 1, NULL, 10);
+                               }
+                       } else {
+                               memset(&bootme_ip, 0xff, sizeof(bootme_ip));
+                       }
+               }
+
+               p = getenv("bootme_dst_port");
+               if (p)
+                       bootme_dst_port = simple_strtoul(p, NULL, 10);
+
+               p = getenv("bootme_src_port");
+               if (p)
+                       bootme_src_port = simple_strtoul(p, NULL, 10);
+               else
+                       bootme_src_port = bootme_dst_port;
+
+               if (is_broadcast(bootme_ip))
+                       memset(bootme_ether, 0xff, sizeof(bootme_ether));
+               else
+                       memset(bootme_ether, 0, sizeof(bootme_ether));
+
+               net_init();
+               NetServerIP = bootme_ip;
+       }
+       return 0;
+}
+
+static void bootme_wait_arp_handler(uchar *pkt, unsigned dest,
+                               IPaddr_t sip, unsigned src,
+                               unsigned len)
+{
+       net_set_state(NETLOOP_SUCCESS); /* got arp reply - quit net loop */
+}
+
+static inline char next_cursor(char c)
+{
+       switch(c) {
+       case '-':
+               return '\\';
+       case '\\':
+               return '|';
+       case '|':
+               return '/';
+       case '/':
+               return '-';
+       }
+       return 0;
+}
+
+static void bootme_handler(uchar *pkt, unsigned dest_port, IPaddr_t src_ip,
+                       unsigned src_port, unsigned len)
+{
+       uchar *eth_pkt = pkt;
+       unsigned eth_len = len;
+       static char cursor = '|';
+       enum bootme_state last_state = bootme_state;
+
+       debug("received packet of len %d from %pI4:%d to port %d\n",
+               len, &src_ip, src_port, dest_port);
+       ce_dump_block(pkt, len);
+
+       if (!bootme_packet_handler) {
+               printf("No packet handler set for BOOTME protocol; dropping packet\n");
+               return;
+       }
+       if (dest_port != bootme_src_port || !len)
+               return; /* not for us */
+
+       printf("%c\x08", cursor);
+       cursor = next_cursor(cursor);
+
+       if (!is_broadcast(bootme_ip) && src_ip != bootme_ip) {
+               debug("src_ip %pI4 does not match destination IP %pI4\n",
+                       &src_ip, &bootme_ip);
+               return; /* not from our server */
+       }
+       if (bootme_state == BOOTME_INIT || bootme_state == BOOTME_DEBUG_INIT) {
+               struct ethernet_hdr *eth = (struct ethernet_hdr *)(pkt -
+                                       NetEthHdrSize() - IP_UDP_HDR_SIZE);
+               memcpy(bootme_ether, eth->et_src, sizeof(bootme_ether));
+               printf("Target MAC address set to %pM\n", bootme_ether);
+
+               if (is_broadcast(bootme_ip)) {
+                       NetCopyIP(&bootme_ip, &src_ip);
+               }
+       }
+       if (bootme_state == BOOTME_INIT) {
+               bootme_src_port = EDBG_SVC_PORT;
+               debug("%s: bootme_src_port set to %d\n", __func__, bootme_src_port);
+       }
+
+       debug("bootme_dst_port %d -> %d\n", bootme_dst_port, src_port);
+       bootme_dst_port = src_port;
+
+       bootme_state = bootme_packet_handler(eth_pkt, eth_len);
+       debug("bootme_packet_handler() returned %d\n", bootme_state);
+       if (bootme_state != last_state)
+               debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+                       last_state, bootme_state);
+       switch (bootme_state) {
+       case BOOTME_INIT:
+       case BOOTME_DEBUG_INIT:
+               break;
+
+       case BOOTME_DOWNLOAD:
+               if (last_state != BOOTME_INIT)
+                       NetBootFileXferSize += len - 4;
+               /* fallthru */
+       case BOOTME_DEBUG:
+               if (last_state == BOOTME_INIT ||
+                       last_state == BOOTME_DEBUG_INIT)
+                       bootme_timeout = 3 * 1000;
+               NetSetTimeout(bootme_timeout, bootme_timeout_handler);
+               break;
+
+       case BOOTME_DONE:
+               net_set_state(NETLOOP_SUCCESS);
+               bootme_packet_handler = NULL;
+               break;
+
+       case BOOTME_ERROR:
+               net_set_state(NETLOOP_FAIL);
+               bootme_packet_handler = NULL;
+       }
+}
+
+void BootmeStart(void)
+{
+       if (bootme_state != BOOTME_DOWNLOAD)
+               check_net_config();
+
+       if (output_packet_len == 0 ||
+               is_valid_ether_addr(bootme_ether)) {
+               /* wait for incoming packet */
+               net_set_udp_handler(bootme_handler);
+               bootme_timed_out = 0;
+               NetSetTimeout(bootme_timeout, bootme_timeout_handler);
+       } else {
+               /* send ARP request */
+               uchar *pkt;
+
+               net_set_arp_handler(bootme_wait_arp_handler);
+               assert(NetTxPacket != NULL);
+               pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
+               memcpy(pkt, output_packet, output_packet_len);
+               debug("%s@%d: Sending ARP request:\n", __func__, __LINE__);
+               ce_dump_block(pkt, output_packet_len);
+               NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
+                               bootme_src_port, output_packet_len);
+               output_packet_len = 0;
+       }
+}
+
+int bootme_send_frame(const void *buf, size_t len)
+{
+       int ret;
+       struct eth_device *eth;
+       uchar *pkt;
+
+       eth = eth_get_dev();
+       if (eth == NULL)
+               return -EINVAL;
+
+       if (bootme_state == BOOTME_INIT || bootme_state == BOOTME_DEBUG_INIT)
+               check_net_config();
+
+       debug("%s: buf: %p len: %u from %pI4:%d to %pI4:%d\n",
+               __func__, buf, len, &NetOurIP, bootme_src_port, &bootme_ip,
+               bootme_dst_port);
+
+       if (is_zero_ether_addr(bootme_ether)) {
+               output_packet = buf;
+               output_packet_len = len;
+               /* wait for arp reply and send packet */
+               ret = NetLoop(BOOTME);
+               if (ret < 0) {
+                       /* drop packet */
+                       output_packet_len = 0;
+                       return ret;
+               }
+               if (bootme_timed_out)
+                       return -ETIMEDOUT;
+               return 0;
+       }
+
+       if (eth->state != ETH_STATE_ACTIVE) {
+               if (eth_is_on_demand_init()) {
+                       ret = eth_init(gd->bd);
+                       if (ret < 0)
+                               return ret;
+                       eth_set_last_protocol(BOOTME);
+               } else {
+                       eth_init_state_only(gd->bd);
+               }
+       }
+
+       assert(NetTxPacket != NULL);
+       pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
+       memcpy(pkt, buf, len);
+
+       ret = NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
+                       bootme_src_port, len);
+       if (ret)
+               printf("Failed to send packet: %d\n", ret);
+
+       return ret;
+}
+
+static void bootme_init(IPaddr_t server_ip)
+{
+       debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+               bootme_state, BOOTME_INIT);
+       bootme_state = BOOTME_INIT;
+       bootme_ip = server_ip;
+       /* force reconfiguration in check_net_config() */
+       env_id = 0;
+}
+
+int BootMeDownload(bootme_hand_f *handler)
+{
+       int ret;
+
+       bootme_packet_handler = handler;
+
+       ret = NetLoop(BOOTME);
+       if (ret < 0)
+               return BOOTME_ERROR;
+       if (bootme_timed_out && bootme_state != BOOTME_INIT)
+               return BOOTME_ERROR;
+
+       return bootme_state;
+}
+
+int BootMeDebugStart(bootme_hand_f *handler)
+{
+       int ret;
+
+       bootme_packet_handler = handler;
+
+       bootme_init(bootme_ip);
+       debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+               bootme_state, BOOTME_DEBUG_INIT);
+       bootme_state = BOOTME_DEBUG_INIT;
+
+       bootme_timeout = 3 * 1000;
+       NetSetTimeout(bootme_timeout, bootme_timeout_handler);
+
+       ret = NetLoop(BOOTME);
+       if (ret < 0)
+               return BOOTME_ERROR;
+       if (bootme_timed_out)
+               return BOOTME_DONE;
+       return bootme_state;
+}
+
+int BootMeRequest(IPaddr_t server_ip, const void *buf, size_t len, int timeout)
+{
+       bootme_init(server_ip);
+       bootme_timeout = timeout * 1000;
+       bootme_timed_out = 0;
+       NetSetTimeout(bootme_timeout, bootme_timeout_handler);
+       return bootme_send_frame(buf, len);
+}
index 81066015f1c2ed28a4fb0ea1ec4bbeecec08047f..5e835a31ad786ada52102b23907777d662046f3f 100644 (file)
@@ -17,7 +17,7 @@
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
 #endif
-#ifdef CONFIG_BOOTP_RANDOM_DELAY
+#if defined(CONFIG_BOOTP_RANDOM_DELAY) || defined(CONFIG_BOOTP_RANDOM_ID)
 #include "net_rand.h"
 #endif
 
@@ -725,6 +725,9 @@ BootpRequest(void)
         *      Bootp ID is the lower 4 bytes of our ethernet address
         *      plus the current time in ms.
         */
+#ifdef CONFIG_BOOTP_RANDOM_ID
+       BootpID = rand();
+#else
        BootpID = ((ulong)NetOurEther[2] << 24)
                | ((ulong)NetOurEther[3] << 16)
                | ((ulong)NetOurEther[4] << 8)
@@ -732,6 +735,7 @@ BootpRequest(void)
        BootpID += get_timer(0);
        BootpID = htonl(BootpID);
        bootp_add_id(BootpID);
+#endif
        NetCopyLong(&bp->bp_id, &BootpID);
 
        /*
index 3b95a0a2ded87596636516c3b1b865aa79cf3aaf..3ffbc51db3b1588855324de3dcd735ad903f3bee 100644 (file)
@@ -59,7 +59,6 @@ struct Bootp_t {
  */
 
 /* bootp.c */
-extern ulong   BootpID;                /* ID of cur BOOTP request      */
 extern char    BootFile[128];          /* Boot file name               */
 extern int     BootpTry;
 
index 2bea07b3cdf671e4dc825b299ada89125f1b89c2..30ecfcc403cfe0b168987d05e39db6e821e864f8 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -439,6 +439,11 @@ restart:
                case LINKLOCAL:
                        link_local_start();
                        break;
+#endif
+#if defined(CONFIG_CMD_BOOTCE)
+               case BOOTME:
+                       BootmeStart();
+                       break;
 #endif
                default:
                        break;
@@ -504,7 +509,7 @@ restart:
                 *      Check for a timeout, and run the timeout handler
                 *      if we have one.
                 */
-               if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
+               if (timeHandler && ((get_timer(timeStart)) > timeDelta)) {
                        thand_f *x;
 
 #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
@@ -544,10 +549,11 @@ restart:
                                setenv_hex("filesize", NetBootFileXferSize);
                                setenv_hex("fileaddr", load_addr);
                        }
-                       if (protocol != NETCONS)
+                       if (protocol != NETCONS) {
                                eth_halt();
-                       else
+                       } else {
                                eth_halt_state_only();
+                       }
 
                        eth_set_last_protocol(protocol);
 
@@ -1208,7 +1214,6 @@ NetReceive(uchar *inpkt, int len)
 static int net_check_prereq(enum proto_t protocol)
 {
        switch (protocol) {
-               /* Fall through */
 #if defined(CONFIG_CMD_PING)
        case PING:
                if (NetPingIP == 0) {
@@ -1248,6 +1253,7 @@ common:
 #endif
                /* Fall through */
 
+       case BOOTME:
        case NETCONS:
        case TFTPSRV:
                if (NetOurIP == 0) {
index ba9d0642cf231ab2ed14c162f2c7fb975f315574..6724b3c13090380d27ffea622ed8cf83df46903e 100644 (file)
@@ -37,7 +37,7 @@ static inline unsigned int seed_mac(void)
  */
 static inline void srand_mac(void)
 {
-       srand(seed_mac());
+       srand(rand() ^ seed_mac());
 }
 
 #endif /* __NET_RAND_H__ */
index 6e1ce79f2f45cd33cc3e99ca278a330adb0f75bd..75ab70563a59fd1c4f1bfac240626afa932d5593 100644 (file)
@@ -52,7 +52,7 @@ HOSTCFLAGS_xway-swap-bytes.o := -pedantic
 hostprogs-y += mkenvimage
 mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o
 
-hostprogs-y += dumpimage mkimage
+#hostprogs-y += dumpimage mkimage
 hostprogs-$(CONFIG_FIT_SIGNATURE) += fit_info fit_check_sign
 
 FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
@@ -205,6 +205,8 @@ HOST_EXTRACFLAGS += -include $(srctree)/include/libfdt_env.h \
                $(patsubst -I%,-idirafter%, $(filter -I%, $(UBOOTINCLUDE))) \
                -I$(srctree)/lib/libfdt \
                -I$(srctree)/tools \
+                -include $(srctree)/include/linux/kconfig.h \
+               -Wno-variadic-macros \
                -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) \
                -DUSE_HOSTCC \
                -D__KERNEL_STRICT_NAMES \
diff --git a/tools/elftosb/COPYING b/tools/elftosb/COPYING
new file mode 100644 (file)
index 0000000..f829e09
--- /dev/null
@@ -0,0 +1,28 @@
+Copyright (c) 2004-2010 Freescale Semiconductor, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list
+  of conditions and the following disclaimer.
+    
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimer in the documentation and/or
+  other materials provided with the distribution.
+    
+* Neither the name of the Freescale Semiconductor, Inc. nor the names of its
+  contributors may be used to endorse or promote products derived from this
+  software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/tools/elftosb/ReadMe.txt b/tools/elftosb/ReadMe.txt
new file mode 100644 (file)
index 0000000..b1fe9bd
--- /dev/null
@@ -0,0 +1,45 @@
+elftosb 2.x read me
+-------------------
+
+Directories
+
+elftosb2 - elftosb 2.x
+sbtool - sbtool 1.x
+keygen - keygen 1.x
+common - source files common between elftosb2, sbtool, and keygen
+winsupport - files needed only by the windows build
+elftosb - old elftosb 1.x, does not use anything from common
+generatekeys - old key generation tool for elftosb 1.x
+decrypt - old decryption tool for elftosb 1.x
+unittests - old unit tests for elftosb 1.x
+test_files - test ELF and Srecord files
+old - contains old makefiles for elftosb 1.x
+
+Development
+
+The preferred way to work on elftosb and related tools is to use Xcode on Mac OS X. The
+elftosb.xcodeproj directory is an Xcode project "file". It has targets for elftosb,
+keygen, sbtool, and an aggregate target that builds all of the above. The main reason
+to use Xcode is that the project is set up so that the flex and bison input files are
+processed automatically and the output files compiled.
+
+The Windows project and Linux makefile are not configured to build the flex or bison
+source files. They simply use the output files copied into the elftosb2 directory.
+You can run flex or bison manually to generate these files if you don't want to use Xcode.
+If you do use the Xcode project and make changes to the .l or .y files, be sure to copy
+the output .cpp files into the elftosb2 directory before you move the changes to either
+Windows or Linux.
+
+Building
+
+On Windows, open the .sln file in Microsoft Visual Studio. The solution contains projects
+for each of the individual projects, including the old elftosb 1.x and related tools.
+
+For Linux, run 'make all' from within the top level elftosb directory. This will build only
+the new elftosb 2.x, sbtool, and keygen. The old makefile to build elftosb 1.x and its
+tools is located in the "old" directory.
+
+On Mac OS X just open the .xcodeproj project and build the "Everything" target.
+
+
+
diff --git a/tools/elftosb/bdfiles/basic_test_cmd.e b/tools/elftosb/bdfiles/basic_test_cmd.e
new file mode 100644 (file)
index 0000000..dbdad1f
--- /dev/null
@@ -0,0 +1,192 @@
+
+# ooh! test input command file for elftosb 2!
+
+options {
+       coalesce = yes;
+
+       # most elf files are GHS produced
+       toolset = "GHS";
+
+       # set versions
+       productVersion = "111.222.333";
+       componentVersion = "999.888.777";
+
+       # set file flags
+       flags = (1 << 0) | (1 << 1);
+}
+
+constants {
+       ocram_start = 0;
+       ocram_size = 256K;
+       ocram_end = ocram_start + ocram_size - 1;
+
+#      ocram = ocram_start .. ocram_end;
+#
+#      ocram = ocram_start +.. ocram_size;
+
+       string_addr = 0x4500;
+
+       # boot modes
+       USB_BM = 0;
+       JTAG_BM = 7;
+       newBootMode = USB_BM;
+}
+
+sources {
+       hello = extern(0);  # elf
+       redboot = extern(1);  # srec
+       hostlink = extern(2); # elf
+       sd_player = extern(3) ( toolset="GCC" ); # elf
+       datasrc = "test0.key"; # binary
+}
+
+section (0) {
+       # load dcd
+       load dcd {{ 00 11 22 33 }} > 0;
+
+       # same load without dcd
+       load {{ 00 11 22 33 }} > 0;
+
+       call 0xf000;
+
+    hab call 0xf0000000 (128);
+       hab jump 0;
+
+/*
+       # load a simple IVT to an absolute address
+       # this fills in the IVT self address field from the target address
+       load ivt (entry=hello:_start) > 0x1000;
+
+       # load simple IVT. the IVT self address is set explicitly in the IVT declaration,
+       # giving the IVT a natural address so you don't have to tell where to load it.
+       load ivt (entry=hello:_start, self=0x1000);
+
+       load ivt (entry=hello:_start, self=0x1000, csf=0x2000, dcd=0);
+
+       # Setting IVT entry point to the default entry point of a source file.
+       load ivt (entry=hostlink) > 0;
+
+       load ivt (entry=hello:_start, self=0x1000);
+       hab call 0x1000;
+
+       # Special syntax that combines the load and call into one statement.
+       hab call ivt(entry=hello:_start, self=0x1000);
+
+
+
+       load ivt (
+           entry = hello:_start,
+           csf = 0x2000
+       ) > 0x1000;
+
+       # All supported IVT fields.
+       load ivt (
+           entry = hello:,
+           dcd = 0,
+           boot_data = 0,
+           self = 0,
+           csf = 0
+       );
+
+       hab call ivt; # Call the last loaded IVT. */
+}
+
+section (32) {
+       # load a string to some address
+       load "some string" > string_addr;
+
+       # byte fill a region
+       load 0x55.b > ocram_start..ocram_end;
+
+       from hostlink {
+               load $*;
+       }
+
+       # jump to a symbol
+       jump hostlink:_start (100);
+}
+
+section (100)
+{
+       load redboot;
+       call redboot;
+}
+
+section(0x5a)
+{
+       load datasrc > 0..8;
+
+       from hostlink
+       {
+#              load $* ( $.ocram.*, ~$.sdram.* );
+
+#              load $.sdram.*;
+#              load $.ocram.*;
+
+               call :main;
+               call :_start;
+       }
+
+#      goto 0x5b;
+}
+
+section (0x5b)
+{
+#      load $* from sd_player;
+
+#      load hello$.text @ 64K;
+#      load hello$*
+
+       load $.text from hello > 0x10000;
+       call sd_player (0xdeadbeef);
+}
+
+section (0x5c)
+{
+       # these loads should produce fill commands with a
+       # length equal to the pattern word size
+       load 0x55.b > 0x200;
+       load 0x55aa.h > 0x400;
+       load 0x55aa66bb.w > 0x800;
+
+#      load 0x55.b to 0x200;
+#      load 0x55aa.h to 0x400;
+#      load 0x55aa66bb.w to 0x800;
+
+#      load 0x55.b @ 0x200;
+#      load 0x55aa.h @ 0x400;
+#      load 0x55aa66bb.w @ 0x800;
+
+#      load $.text from hello @ .;
+#      load hello$.text @ .;
+#      load hello$* @ .
+
+       # this should produce a fill command with a length
+       # of 0x100
+       load 0x4c8e.h > 0x100..0x200;
+
+#      load [ 0a 9b 77 66 55 44 33 22 11 00 ] @ 0x100;
+}
+
+# non-bootable section
+section (0x100) <= datasrc;
+
+#section (1K)
+#{
+#      load 0xff.b > hostlink:g_wUsbVID + 4;
+#
+#      load "Fred's Auto Service\x00" > hostlink:g_wUsbVendorName;
+#
+#      from sd_player
+#      {
+#              load [ 00 11 22 33 44 55 66 77 ] > :g_data + 16;
+#      }
+#
+##     (0x10 .. 0x20) + 5  ==  0x15 .. 0x25
+#}
+
+# section that switches modes
+section (2K)
+{
+       mode newBootMode;
+}
diff --git a/tools/elftosb/bdfiles/complex.bd b/tools/elftosb/bdfiles/complex.bd
new file mode 100644 (file)
index 0000000..4038a52
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2006 SigmaTel, Inc.
+ *
+ * elftosb boot description file that creates some complicated situations for
+ * the loader to handle. of course this is also a good test for elftosb itself.
+ */
+
+/* testing C style comments */
+// testing C++ style comments
+# testing shell style comments
+
+constants {
+       kProgressReportsImageFlag = 0x1;
+       
+       kPlayerDriveTag = 0xa0;
+       kHostlinkDriveTag = 0xb0;
+}
+
+options {
+       productVersion = "5.0.999";
+       componentVersion = "5.0.999";
+    
+    flags = kProgressReportsImageFlag;  // turn on progress reports
+       
+       secinfoClear = "ignore";
+}
+
+constants {
+    arg = 0xfeedf00d;
+    
+    callArg1 = 2;
+    callArg2 = 3;
+    
+    halfword = 10.h;
+    
+//    flag = 1;
+       
+       testboolexpr = 1 > 0;
+       
+       mainSizeIsDefined = defined(mainSize);
+}
+
+sources {
+    elffile = extern(0) (toolset="ghs");
+    binfile1 = extern(1);
+    binfile2 = extern(2);
+    foofile = "file.dat";
+    anotherfile = "another.dat";
+       srecfile = "test_files/sd_player_gcc.srec";
+}
+
+options {
+       driveTag = kPlayerDriveTag;
+       
+       some_option = defined(testboolexpr);
+}
+
+constants {
+       printMessageAddr = elffile:printMessage;
+       printMessageSize = sizeof(elffile:printMessage);
+       
+       // create const with address of main() in elffile
+       mainAddr = elffile:main;
+       
+       mainSize = sizeof(elffile:main);
+       
+       halfwordSize = sizeof(halfword);
+       
+       elf_startAddr = elffile:_start;
+       
+//     poop = exists(nonexistantfile);
+
+       binfile1size = sizeof(binfile1);
+}
+
+/*
+ * test s-record support
+ */
+section (0)
+{
+       load dcd {{ 00 11 22 33 }} > 0;
+       load srecfile;
+       call srecfile;
+}
+
+section(1; coalesce=true) {
+       
+       info "welcome to section 1!";
+       info "elffile path = $(elffile)";
+       info "mainSizeIsDefined = $(d:mainSizeIsDefined)";
+       info "printMessage = $(x:printMessageAddr)";
+       
+       info "size of binfile1 = $(binfile1size)";
+       
+       // can use symbol refs inside bool expressions in an if stmt
+       if elffile:main == 0
+       {
+               warning "$(elffile) does not seem to have a main() function";
+       }
+       else
+       {
+               info "address of main() of $(elffile) is $(x:mainAddr)";
+       }
+       
+       if defined(flag) && flag != 0
+       {
+               load 0x1234.h > 0..10K;
+       }
+       else
+       {
+               // print message using both decimal and hex formatting
+               warning "loading only halfword = $(d:halfword) [$(x:halfword)]!";
+               load halfword > 0..1K;
+       }
+       
+       info "size of main() in $(elffile) is $(mainSize)";
+       info "printMessage() size is $(printMessageSize)";
+       info "size of halfword = $(halfwordSize)";
+       
+       load 0xff.b > 32K..32K + sizeof(elffile:printMessage);
+       
+       from elffile {
+       load {{ 00 01 02 03 04 }} > 1K;
+               
+               // load all sections except .mytext
+               load ~$.mytext;
+               
+               // figure out where to go from here
+               call :maybeSwitchSections(callArg1);
+               
+               // print msg and loop
+               load "hi from section 1" > :szMsg;
+               call :printMessage(0);
+               
+               jump :hello(0);
+       }
+       
+       // erase a function in memory
+       load 0.w > (elffile:endOfLine)..(elffile:endOfLine + sizeof(elffile:endOfLine));
+}
+
+section(2; alignment=64K) {
+       // cause an error if testConst has not been set
+       if !defined(testConst)
+       {
+               error "testConst is not defined!";
+       }
+       
+    from elffile {
+        load "in section 2" > :szMsg;
+        call :printMessage();
+    }
+    
+    // load the contents of binfile1 into the upper 128KB of ocram
+    load binfile1 > 128K..192K;
+    
+    from elffile {
+        load "loaded binfile1" > :szMsg;
+        call :printMessage(0);
+        
+        call :maybeSwitchSections(callArg2);
+        
+        jump :endOfLine(2);
+    }
+}
+
+// non-bootable section between two bootable sections
+section(0xbeef; alignment=32K, cleartext=false) <= binfile2;
+
+section(3; alignment=8K) {
+    // load our special section
+    load $.mytext from elffile;
+    call elffile:countToN(5);
+    
+       if (exists(foofile) && exists(anotherfile))
+       {
+               // a trainload of beef!
+               load 0xbeef.h > 128K..192K;
+       }
+       else if (exists(elffile) && callArg1 == 2)
+       {
+               // aaaaaaah!
+               load 0x12345678.w > 128K..192K;
+       }
+       else
+       {
+               from elffile
+               {
+                       // aaaaaaah!
+                       load 0xaaaa.h > 128K..192K;
+                       load $.text;
+                       load 0xbbbb.h > 128K..192K;
+               }
+       }
+    
+    from elffile {
+        load "hold on now, in section 3" > :szMsg;
+        call :printMessage(0);
+        
+        jump :endOfLine(3);
+    }
+    
+    from elffile {
+       load elffile;
+       load elffile > .;
+       load elffile[ $.bss ] > elffile:countToN;
+//             load [ $.bss ] > (elffile:countToN)..(elffile:countToN + sizeof(elffile:countToN));
+       call elffile;
+       call elffile(1);
+    }
+    
+    info "address of _start in $(elffile) is $(elf_startAddr)";
+}
+
+section ('four'; alignment=8K, sectionFlags=0x1000) <= binfile1;
+
+section ('five'; alignment=8K, cleartext=1, sectionFlags=0x1000) <= binfile1;
+
+/*
+ * create a data section out of some sections of an elf file
+ */
+section (1234) <= ~$.bss, ~$.data from elffile;
+section (4321) <= elffile [ $* ];
+section (1111) <= elffile;
+
+/* test data sections from various data sources */
+section (0xaa) <= 0x12345678.w;
+section (0xbb) <= "hi there! this is a data section.";
+section (0xcc) <= {{ aa55aa55aa55aa55aa55aa55aa55aa55 }};
+
+
+section (2345)
+{
+       load elffile[ $*.text*, ~$.sdram* ];
+}
+
+
+section ('six_')
+{
+       // load a blob at address 0x1000
+       load {{
+               00 0a 07 b0 bb ff 03 78
+               00 0a 07 b0 bb ff 03 78
+               00 0a 07 b0 bb ff 03 78
+               00 0a 07 b0 bb ff 03 78
+               00 0a 07 b0 bb ff 03 78
+       }} > 0x1000;
+}
+
+section ('bad_')
+{
+       // uncomment to test better error reporting for files that failed to open
+//     load foofile;
+}
+
+//section (2345) <= {{ 00 11 22 33 44 55 }};
+
+
+
+
diff --git a/tools/elftosb/bdfiles/habtest.bd b/tools/elftosb/bdfiles/habtest.bd
new file mode 100644 (file)
index 0000000..25fc8de
--- /dev/null
@@ -0,0 +1,36 @@
+sources {
+    elffile = extern(0) (toolset="ghs");
+    redboot = extern(1);
+    hostlink = extern(2);
+       srecfile = "test_files/sd_player_gcc.srec";
+}
+
+constants {
+    IVT_ADDR = 0x1000;
+}
+
+section (0)
+{
+
+    load hostlink;
+    call hostlink;
+
+    load dcd {{ 00 11 22 33 }} > 0x100;
+
+    load ivt (
+        entry = elffile:_start
+//        dcd = 0x2000,
+//        csf = 0x3000,
+//        boot_data = 0x55aa55aa.w
+//        self = IVT_ADDR
+    ) > IVT_ADDR;
+
+    hab call IVT_ADDR;
+
+    load ivt (entry=hostlink:_start, self=IVT_ADDR);
+
+    hab jump IVT_ADDR;
+}
+
+
+
diff --git a/tools/elftosb/bdfiles/simple.e b/tools/elftosb/bdfiles/simple.e
new file mode 100644 (file)
index 0000000..65ac5e8
--- /dev/null
@@ -0,0 +1,8 @@
+options {}\r
+\r
+# create a section\r
+section (0) {\r
+    load 0 > 0..256K;\r
+    load "hello world!" > 0x1000;\r
+}\r
+\r
diff --git a/tools/elftosb/bdfiles/test_cmd.e b/tools/elftosb/bdfiles/test_cmd.e
new file mode 100644 (file)
index 0000000..29af510
--- /dev/null
@@ -0,0 +1,120 @@
+
+# ooh! test input command file for elftosb 2!
+
+options {
+       searchPath = "elftosb2:elftosb2/elf_test_files";
+       
+       maximumLoadBlock = 4K;
+       sectionAlign = 4K;
+       
+       productVersion = "4.4.720";
+       componentVersion = "4.4.999";
+       
+       coalesce = yes;
+}
+
+constants {
+       ocram_start = 0;
+       ocram_size = 256K;
+       ocram_end = ocram_start + ocram_size - 1;
+       
+       prec_test = 1 + 5 * 10;
+       paren_test = (1 + 5) * 10;
+       
+       a = 123;
+       foo = (1 + 0x1cf1.w).w ^ 5 + a;
+       
+       bar1 = 0xa << 2;
+       bar2 = bar1 | 0x1000;
+       bar3 = bar2 & 0x5555;
+       bar4 = bar3 >> 1;
+       
+       mod = 35 % 16;
+       
+       n = -1;
+       x = 1 + -2;
+       
+       c1 = 'x';
+       c2 = 'oh';
+       c4 = 'shit';
+       
+       # test int size promotion
+       x = 0xff.b;
+       y = 0x1234.h;
+       z = 0x55aa55aa.w;
+       xx = x - (x / 2.b);     # should produce byte
+       xy = x + y;                     # should produce half-word
+       xz = x - z;                     # should produce word
+       yz = y + z;                     # should produce word
+       xh = x.h;
+       xw = x.w;
+}
+
+sources {
+       hostlink = extern(0);
+       redboot = extern(1);
+       
+       sd_player_elf="elftosb2/elf_test_files/sd_player_gcc";
+       sd_player_srec="elftosb2/elf_test_files/sd_player_gcc.srec";
+       
+       datafile="elftosb2/elf_test_files/hello_NOR_arm";
+}
+
+#section('foo!') {
+#      load 0.w > ocram_start..ocram_end;      # word fill all ocram with 0
+#      
+#      load hostlink;                                  # load all of hostlink source
+#      
+#      load 0x1000ffff.w > 0x1000;             # load a word to address 0x1000
+#      load 0x55aa.h > 0x2000;                 # load a half-word to address 0x2000
+#      load redboot;                                   # load all sections of redboot source
+#      
+#      from hostlink {
+#         load $.*.text;                               # load some sections to their natural location
+#         call :_start;                                # call function "_start" from hostlink
+#         call hostlink:foofn;                 # call function "foofn" from hostlink
+#         
+#         call :monkey (1 + 1);                # call function "monkey" from hostlink with an argument
+#         
+#         load $* > .;                                 # load all sections of hostlink to their natural location
+#         
+#         load $.text > 0x1000;                # load .text section to address 0x1000
+#         
+#         load 0x55.b > 0x0..0x4000;   # fill 0 through 0x4000 with byte pattern 0x55
+#      }
+#      
+#      load $*.text from hostlink > .; # load sections match "*.text" from hostlink to default places
+#      
+#      jump redboot;                                   # jump to entry point of redboot source
+#}
+
+## this section...
+#section(2) {
+#      from sd_player_elf {
+#              load $* > .;
+#              call :_start();
+#      }
+#}
+#
+## and this one are both equivalent except for section ids
+#section(3) {
+#      load $* from sd_player_elf;
+#      call sd_player_elf:_start();
+#}
+#
+#section(100) {
+#    # set the value of a symbol
+#    load hostlink;
+#    load 0x5555.h > hostlink:g_USBPID;
+#    
+#    # load a string to memory
+#    load "this is a string" > 0x1e0;
+#}
+
+section (32) {
+       load sd_player_srec;
+       call sd_player_srec;
+}
+
+#section('rsrc') <= datafile;
+
diff --git a/tools/elftosb/common/AESKey.cpp b/tools/elftosb/common/AESKey.cpp
new file mode 100644 (file)
index 0000000..eedab32
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * File:       AESKey.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "AESKey.h"
+#include <stdexcept>
+#include "smart_ptr.h"
+#include "HexValues.h"
+#include <ctype.h>
+
+//! The data from the stream is expected to be hex encoded. Each two characters
+//! from the stream encode a single result byte. All non-hexadecimal characters
+//! are ignored, including newlines. Every two hexadecimal characters form
+//! an encoded byte. This is true even if the two characters representing the
+//! upper and lower nibbles are separated by whitespace or other characters.
+//!
+//! \post The stream read head is left pointing just after the last encoded byte.
+//!
+//! \param stream Input stream to read from.
+//! \param bytes Number of encoded bytes to read. This is the number of \e
+//!            result bytes, not the count of bytes to read from the stream.
+//! \param[out] buffer Pointer to the buffer where decoded data is written.
+//!
+//! \exception std::runtime_error This exception will be thrown if less
+//!            data than required is available from \a stream, or if some other
+//!            error occurs while reading from \a stream.
+void AESKeyBase::_readFromStream(std::istream & stream, unsigned bytes, uint8_t * buffer)
+{
+       char temp[2];
+       char c;
+       char n = 0;
+       
+       while (bytes)
+       {
+               if (stream.get(c).fail())
+               {
+                       throw std::runtime_error("not enough data in stream");
+               }
+               
+               if (isHexDigit(c))
+               {
+                       temp[n++] = c;
+                       if (n == 2)
+                       {
+                               *buffer++ = hexByteToInt(temp);
+                               bytes--;
+                               n = 0;
+                       }
+               }
+       }
+}
+
+//! Key data is written to \a stream as a sequence of hex encoded octets, each two
+//! characters long. No spaces or newlines are inserted between the encoded octets
+//! or at the end of the sequence.
+//!
+//! \exception std::runtime_error Thrown if the \a stream reports an error while
+//!            writing the key data.
+void AESKeyBase::_writeToStream(std::ostream & stream, unsigned bytes, const uint8_t * buffer)
+{
+       const char hexChars[] = "0123456789ABCDEF";
+       while (bytes--)
+       {
+               uint8_t thisByte = *buffer++;
+               char byteString[2];
+               byteString[0] = hexChars[(thisByte & 0xf0) >> 4];
+               byteString[1] = hexChars[thisByte & 0x0f];
+               if (stream.write(byteString, 2).bad())
+               {
+                       throw std::runtime_error("error while writing to stream");
+               }
+       }
+}
+
+
diff --git a/tools/elftosb/common/AESKey.h b/tools/elftosb/common/AESKey.h
new file mode 100644 (file)
index 0000000..b92b1ae
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * File:       AESKey.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_AESKey_h_)
+#define _AESKey_h_
+
+#include "stdafx.h"
+#include <string.h>
+#include <iostream>
+#include "Random.h"
+
+//! An AES-128 key is 128 bits, or 16 bytes.
+typedef uint8_t aes128_key_t[16];
+
+/*!
+ * \brief Base class for AESKey<S>.
+ *
+ * This class implements some bigger, non-template methods used in the
+ * AESKey<S> templated subclass.
+ */
+class AESKeyBase
+{
+public:
+       //! \brief Reads hex encoded data from \a stream.
+       void _readFromStream(std::istream & stream, unsigned bytes, uint8_t * buffer);
+       
+       //! \brief Writes hex encoded data to \a stream.
+       void _writeToStream(std::ostream & stream, unsigned bytes, const uint8_t * buffer);
+};
+
+/*!
+ * \brief Generic AES key class.
+ *
+ * The template parameter \a S is the number of bits in the key.
+ *
+ * The underlying key type can be accessed like this: AESKey<128>::key_t
+ *
+ * When a key instance is destroyed, it erases the key data by setting it
+ * to all zeroes.
+ *
+ * \todo Add a way to allow only key sizes of 128, 192, and 256 bits.
+ * \todo Find a cross platform way to prevent the key data from being written
+ *             to the VM swapfile.
+ *
+ * AESKey<128> key = AESKey<128>::readFromStream(s);
+ */
+template <int S>
+class AESKey : public AESKeyBase
+{
+public:
+       //! Type for this size of AES key.
+       typedef uint8_t key_t[S/8];
+       
+public:
+       //! \brief Default constructor.
+       //!
+       //! Initializes the key to 0.
+       AESKey()
+       {
+               memset(m_key, 0, sizeof(m_key));
+       }
+       
+       //! \brief Constructor taking a key value reference.
+       AESKey(const key_t & key)
+       {
+               memcpy(m_key, &key, sizeof(m_key));
+       }
+       
+       // \brief Constructor taking a key value pointer.
+       AESKey(const key_t * key)
+       {
+               memcpy(m_key, key, sizeof(m_key));
+       }
+       
+       //! \brief Constructor, reads key from stream in hex format.
+       AESKey(std::istream & stream)
+       {
+               readFromStream(stream);
+       }
+       
+       //! \brief Copy constructor.
+       AESKey(const AESKey<S> & other)
+       {
+               memcpy(m_key, other.m_key, sizeof(m_key));
+       }
+       
+       //! \brief Destructor.
+       //!
+       //! Sets the key value to zero.
+       ~AESKey()
+       {
+               memset(m_key, 0, sizeof(m_key));
+       }
+       
+       //! \brief Set to the key to a randomly generated value.
+       void randomize()
+       {
+               RandomNumberGenerator rng;
+               rng.generateBlock(m_key, sizeof(m_key));
+       }
+       
+       //! \brief Reads the key from a hex encoded data stream.
+       void readFromStream(std::istream & stream)
+       {
+               _readFromStream(stream, S/8, reinterpret_cast<uint8_t*>(&m_key));
+       }
+       
+       //! \brief Writes the key to a data stream in hex encoded format.
+       void writeToStream(std::ostream & stream)
+       {
+               _writeToStream(stream, S/8, reinterpret_cast<uint8_t*>(&m_key));
+       }
+       
+       //! \name Key accessors
+       //@{
+       inline const key_t & getKey() const { return m_key; }
+       inline void getKey(key_t * key) const { memcpy(key, m_key, sizeof(m_key)); }
+       
+       inline void setKey(const key_t & key) { memcpy(m_key, &key, sizeof(m_key)); }
+       inline void setKey(const key_t * key) { memcpy(m_key, key, sizeof(m_key)); }
+       inline void setKey(const AESKey<S> & key) { memcpy(m_key, key.m_key, sizeof(m_key)); }
+       //@}
+       
+       //! \name Operators
+       //@{
+       const AESKey<S> & operator = (const AESKey<S> & key) { setKey(key); return *this; }
+       const AESKey<S> & operator = (const key_t & key) { setKey(key); return *this; }
+       const AESKey<S> & operator = (const key_t * key) { setKey(key); return *this; }
+       
+       operator const key_t & () const { return m_key; }
+       operator const key_t * () const { return m_key; }
+       //@}
+       
+protected:
+       key_t m_key;    //!< The key value.
+};
+
+//! Standard type definition for an AES-128 key.
+typedef AESKey<128> AES128Key;
+
+#endif // _AESKey_h_
diff --git a/tools/elftosb/common/Blob.cpp b/tools/elftosb/common/Blob.cpp
new file mode 100644 (file)
index 0000000..3d02521
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * File:       Blob.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "Blob.h"
+#include <stdexcept>
+#include <stdlib.h>
+#include <string.h>
+
+Blob::Blob()
+:      m_data(0),
+       m_length(0)
+{
+}
+
+//! Makes a local copy of the \a data argument.
+//!
+Blob::Blob(const uint8_t * data, unsigned length)
+:      m_data(0),
+       m_length(length)
+{
+       m_data = reinterpret_cast<uint8_t*>(malloc(length));
+       memcpy(m_data, data, length);
+}
+
+//! Makes a local copy of the data owned by \a other.
+//!
+Blob::Blob(const Blob & other)
+:      m_data(0),
+       m_length(other.m_length)
+{
+       m_data = reinterpret_cast<uint8_t *>(malloc(m_length));
+       memcpy(m_data, other.m_data, m_length);
+}
+
+//! Disposes of the binary data associated with this object.
+Blob::~Blob()
+{
+       if (m_data)
+       {
+               free(m_data);
+       }
+}
+
+//! Copies \a data onto the blob's data. The blob does not assume ownership
+//! of \a data.
+//!
+//! \param data Pointer to a buffer containing the data which will be copied
+//!            into the blob.
+//! \param length Number of bytes pointed to by \a data.
+void Blob::setData(const uint8_t * data, unsigned length)
+{
+       setLength(length);
+       memcpy(m_data, data, length);
+}
+
+//! Sets the #m_length member variable to \a length and resizes #m_data to
+//! the new length. The contents of #m_data past any previous contents are undefined.
+//! If the new \a length is 0 then the data will be freed and a subsequent call
+//! to getData() will return NULL.
+//!
+//! \param length New length of the blob's data in bytes.
+void Blob::setLength(unsigned length)
+{
+       if (length == 0)
+       {
+               clear();
+               return;
+       }
+       
+       // Allocate new block.
+       if (!m_data)
+       {
+               m_data = reinterpret_cast<uint8_t*>(malloc(length));
+               if (!m_data)
+               {
+                       throw std::runtime_error("failed to allocate memory");
+               }
+       }
+       // Reallocate previous block.
+       else
+       {
+               void * newBlob = realloc(m_data, length);
+               if (!newBlob)
+               {
+                       throw std::runtime_error("failed to reallocate memory");
+               }
+               m_data = reinterpret_cast<uint8_t*>(newBlob);
+       }
+       
+       // Set length.
+       m_length = length;
+}
+
+void Blob::append(const uint8_t * newData, unsigned newDataLength)
+{
+       unsigned oldLength = m_length;
+       
+       setLength(m_length + newDataLength);
+       
+       memcpy(m_data + oldLength, newData, newDataLength);
+}
+
+void Blob::clear()
+{
+       if (m_data)
+       {
+               free(m_data);
+               m_data = NULL;
+       }
+       
+       m_length = 0;
+}
+
+void Blob::relinquish()
+{
+       m_data = NULL;
+       m_length = 0;
+}
+
diff --git a/tools/elftosb/common/Blob.h b/tools/elftosb/common/Blob.h
new file mode 100644 (file)
index 0000000..e7753b3
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * File:       Blob.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_Blob_h_)
+#define _Blob_h_
+
+#include "stdafx.h"
+
+/*!
+ * \brief Manages a binary object of arbitrary length.
+ *
+ * The data block is allocated with malloc() instead of the new
+ * operator so that we can use realloc() to resize it.
+ */
+class Blob
+{
+public:
+       //! \brief Default constructor.
+       Blob();
+       
+       //! \brief Constructor.
+       Blob(const uint8_t * data, unsigned length);
+       
+       //! \brief Copy constructor.
+       Blob(const Blob & other);
+       
+       //! \brief Destructor.
+       virtual ~Blob();
+       
+       //! \name Operations
+       //@{
+       //! \brief Replaces the blob's data.
+       void setData(const uint8_t * data, unsigned length);
+       
+       //! \brief Change the size of the blob's data.
+       void setLength(unsigned length);
+       
+       //! \brief Adds data to the end of the blob.
+       void append(const uint8_t * newData, unsigned newDataLength);
+       
+       //! \brief Disposes of the data.
+       void clear();
+       
+       //! \brief Tell the blob that it no longer owns its data.
+       void relinquish();
+       //@}
+       
+       //! \name Accessors
+       //@{
+       uint8_t * getData() { return m_data; }
+       const uint8_t * getData() const { return m_data; }
+       unsigned getLength() const { return m_length; }
+       //@}
+       
+       //! \name Operators
+       //@{
+       operator uint8_t * () { return m_data; }
+       operator const uint8_t * () const { return m_data; }
+       //@}
+
+protected:
+       uint8_t * m_data;       //!< The binary data held by this object.
+       unsigned m_length;      //!< Number of bytes pointed to by #m_data.
+};
+
+#endif // _Blob_h_
+
diff --git a/tools/elftosb/common/BootImage.h b/tools/elftosb/common/BootImage.h
new file mode 100644 (file)
index 0000000..4ca2c21
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * File:       BootImage.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_BootImage_h_)
+#define _BootImage_h_
+
+#include <iostream>
+#include "Version.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Abstract base class for all boot image format classes.
+ *
+ * Provides virtual methods for all of the common features between different
+ * boot image formats. These are the product and component version numbers
+ * and the drive tag.
+ *
+ * Also provided is the virtual method writeToStream() that lets the caller
+ * stream out the boot image without knowing the underlying format type.
+ */
+class BootImage
+{
+public:
+       //! \brief Constructor.
+       BootImage() {}
+       
+       //! \brief Destructor.
+       virtual ~BootImage() {}
+       
+       //! \name Versions
+       //@{
+       virtual void setProductVersion(const version_t & version)=0;
+       virtual void setComponentVersion(const version_t & version)=0;
+       //@}
+       
+       //! \brief Specify the drive tag to be set in the output file header.
+       virtual void setDriveTag(uint16_t tag)=0;
+
+       //! \brief Returns a string containing the preferred file extension for image format.
+       virtual std::string getFileExtension() const=0;
+       
+       //! \brief Write the boot image to an output stream.
+       virtual void writeToStream(std::ostream & stream)=0;
+};
+
+}; // namespace elftosb
+
+#endif // _BootImage_h_
+
diff --git a/tools/elftosb/common/DataSource.cpp b/tools/elftosb/common/DataSource.cpp
new file mode 100644 (file)
index 0000000..214104b
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * File:       DataSource.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "DataSource.h"
+#include "DataTarget.h"
+#include <assert.h>
+#include <string.h>
+using namespace elftosb;
+
+#pragma mark *** DataSource::PatternSegment ***
+
+DataSource::PatternSegment::PatternSegment(DataSource & source)
+:      DataSource::Segment(source), m_pattern()
+{
+}
+
+DataSource::PatternSegment::PatternSegment(DataSource & source, const SizedIntegerValue & pattern)
+:      DataSource::Segment(source), m_pattern(pattern)
+{
+}
+
+DataSource::PatternSegment::PatternSegment(DataSource & source, uint8_t pattern)
+:      DataSource::Segment(source), m_pattern(static_cast<uint8_t>(pattern))
+{
+}
+
+DataSource::PatternSegment::PatternSegment(DataSource & source, uint16_t pattern)
+:      DataSource::Segment(source), m_pattern(static_cast<uint16_t>(pattern))
+{
+}
+
+DataSource::PatternSegment::PatternSegment(DataSource & source, uint32_t pattern)
+:      DataSource::Segment(source), m_pattern(static_cast<uint32_t>(pattern))
+{
+}
+
+unsigned DataSource::PatternSegment::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)
+{
+       memset(buffer, 0, maxBytes);
+       
+       return maxBytes;
+}
+
+//! The pattern segment's length is a function of the data target. If the
+//! target is bounded, then the segment's length is simply the target's
+//! length. Otherwise, if no target has been set or the target is unbounded,
+//! then the length returned is 0.
+unsigned DataSource::PatternSegment::getLength()
+{
+       DataTarget * target = m_source.getTarget();
+       if (!target)
+       {
+               return 0;
+       }
+       
+       uint32_t length;
+       if (target->isBounded())
+       {
+               length = target->getEndAddress() - target->getBeginAddress();
+       }
+       else
+       {
+               length = m_pattern.getSize();
+       }
+       return length;
+}
+
+#pragma mark *** PatternSource ***
+
+PatternSource::PatternSource()
+:      DataSource(), DataSource::PatternSegment((DataSource&)*this)
+{
+}
+
+PatternSource::PatternSource(const SizedIntegerValue & value)
+:      DataSource(), DataSource::PatternSegment((DataSource&)*this, value)
+{
+}
+
+#pragma mark *** UnmappedDataSource ***
+
+UnmappedDataSource::UnmappedDataSource()
+:      DataSource(), DataSource::Segment((DataSource&)*this), m_data(), m_length(0)
+{
+}
+
+UnmappedDataSource::UnmappedDataSource(const uint8_t * data, unsigned length)
+:      DataSource(), DataSource::Segment((DataSource&)*this), m_data(), m_length(0)
+{
+       setData(data, length);
+}
+
+//! Makes a copy of \a data that is freed when the data source is
+//! destroyed. The caller does not have to maintain \a data after this call
+//! returns.
+void UnmappedDataSource::setData(const uint8_t * data, unsigned length)
+{
+       m_data.safe_delete();
+       
+       uint8_t * dataCopy = new uint8_t[length];
+       memcpy(dataCopy, data, length);
+       m_data = dataCopy;
+       m_length = length;
+}
+
+unsigned UnmappedDataSource::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)
+{
+       assert(offset < m_length);
+       unsigned copyBytes = std::min<unsigned>(m_length - offset, maxBytes);
+       memcpy(buffer, m_data.get(), copyBytes);
+       return copyBytes;
+}
+
+#pragma mark *** MemoryImageDataSource ***
+
+MemoryImageDataSource::MemoryImageDataSource(StExecutableImage * image)
+:      DataSource(), m_image(image)
+{
+       // reserve enough room for all segments
+       m_segments.reserve(m_image->getRegionCount());
+}
+
+MemoryImageDataSource::~MemoryImageDataSource()
+{
+       segment_array_t::iterator it = m_segments.begin();
+       for (; it != m_segments.end(); ++it)
+       {
+               // delete this segment if it has been created
+               if (*it)
+               {
+                       delete *it;
+               }
+       }
+}
+
+unsigned MemoryImageDataSource::getSegmentCount()
+{
+       return m_image->getRegionCount();
+}
+
+DataSource::Segment * MemoryImageDataSource::getSegmentAt(unsigned index)
+{
+       // return previously created segment
+       if (index < m_segments.size() && m_segments[index])
+       {
+               return m_segments[index];
+       }
+       
+       // extend array out to this index
+       if (index >= m_segments.size() && index < m_image->getRegionCount())
+       {
+               m_segments.resize(index + 1, NULL);
+       }
+       
+       // create the new segment object
+       DataSource::Segment * newSegment;
+       const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(index);
+       if (region.m_type == StExecutableImage::TEXT_REGION)
+       {
+               newSegment = new TextSegment(*this, m_image, index);
+       }
+       else if (region.m_type == StExecutableImage::FILL_REGION)
+       {
+               newSegment = new FillSegment(*this, m_image, index);
+       }
+       
+       m_segments[index] = newSegment;
+       return newSegment;
+}
+
+#pragma mark *** MemoryImageDataSource::TextSegment ***
+
+MemoryImageDataSource::TextSegment::TextSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index)
+:      DataSource::Segment(source), m_image(image), m_index(index)
+{
+}
+
+unsigned MemoryImageDataSource::TextSegment::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)
+{
+       const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
+       assert(region.m_type == StExecutableImage::TEXT_REGION);
+       
+       unsigned copyBytes = std::min<unsigned>(region.m_length - offset, maxBytes);    
+       memcpy(buffer, &region.m_data[offset], copyBytes);
+       
+       return copyBytes;
+}
+
+unsigned MemoryImageDataSource::TextSegment::getLength()
+{
+       const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
+       return region.m_length;
+}
+
+uint32_t MemoryImageDataSource::TextSegment::getBaseAddress()
+{
+       const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
+       return region.m_address;
+}
+
+#pragma mark *** MemoryImageDataSource::FillSegment ***
+
+MemoryImageDataSource::FillSegment::FillSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index)
+:      DataSource::PatternSegment(source), m_image(image), m_index(index)
+{
+       SizedIntegerValue zero(0, kWordSize);
+       setPattern(zero);
+}
+
+unsigned MemoryImageDataSource::FillSegment::getLength()
+{
+       const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
+       return region.m_length;
+}
+
+uint32_t MemoryImageDataSource::FillSegment::getBaseAddress()
+{
+       const StExecutableImage::MemoryRegion & region = m_image->getRegionAtIndex(m_index);
+       return region.m_address;
+}
diff --git a/tools/elftosb/common/DataSource.h b/tools/elftosb/common/DataSource.h
new file mode 100644 (file)
index 0000000..4fb9f00
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * File:       DataSource.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_DataSource_h_)
+#define _DataSource_h_
+
+#include <vector>
+#include "Value.h"
+#include "smart_ptr.h"
+#include "StExecutableImage.h"
+
+namespace elftosb
+{
+
+// Forward declaration
+class DataTarget;
+
+/*!
+ * \brief Abstract base class for data sources.
+ *
+ * Data sources represent any sort of data that can be placed or loaded
+ * into a target region. Sources may be a single blob of data read from
+ * a file or may consist of many segments.
+ *
+ * The three most important features of data sources are:
+ * - Sources may be multi-segmented.
+ * - Sources and/or segments can have a "natural" or default target location.
+ * - The target for a source may be taken into consideration when the source
+ *             describes itself.
+ */
+class DataSource
+{
+public:
+       /*!
+        * \brief Discrete, contiguous part of the source's data.
+        *
+        * This class is purely abstract and subclasses of DataSource are expected
+        * to subclass it to implement a segment particular to their needs.
+        */
+       class Segment
+       {
+       public:
+               //! \brief Default constructor.
+               Segment(DataSource & source) : m_source(source) {}
+               
+               //! \brief Destructor.
+               virtual ~Segment() {}
+               
+               //! \brief Gets all or a portion of the segment's data.
+               //!
+               //! The data is copied into \a buffer. Up to \a maxBytes bytes may be
+               //! copied, so \a buffer must be at least that large.
+               //!
+               //! \param offset Index of the first byte to start copying from.
+               //! \param maxBytes The maximum number of bytes that can be returned. \a buffer
+               //!             must be at least this large.
+               //! \param buffer Pointer to buffer where the data is copied.
+               //! \return The number of bytes copied into \a buffer.
+               virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)=0;
+               
+               //! \brief Gets the length of the segment's data.
+               virtual unsigned getLength()=0;
+               
+               //! \brief Returns whether the segment has an associated address.
+               virtual bool hasNaturalLocation()=0;
+               
+               //! \brief Returns the address associated with the segment.
+               virtual uint32_t getBaseAddress() { return 0; }
+       
+       protected:
+               DataSource & m_source;  //!< The data source to which this segment belongs.
+       };
+       
+       /*!
+        * \brief This is a special type of segment containing a repeating pattern.
+        *
+        * By default the segment doesn't have a specific length or data. The length depends
+        * on the target's address range. And the data is just the pattern, repeated
+        * many times. In addition, pattern segments do not have a natural location.
+        *
+        * Calling code should look for instances of PatternSegment and handle them
+        * as special cases that can be optimized.
+        */
+       class PatternSegment : public Segment
+       {
+       public:
+               //! \brief Default constructor.
+               PatternSegment(DataSource & source);
+               
+               //! \brief Constructor taking a fill pattern.
+               PatternSegment(DataSource & source, const SizedIntegerValue & pattern);
+               
+               //! \brief Constructor taking a byte fill pattern.
+               PatternSegment(DataSource & source, uint8_t pattern);
+               
+               //! \brief Constructor taking a half-word fill pattern.
+               PatternSegment(DataSource & source, uint16_t pattern);
+               
+               //! \brief Constructor taking a word fill pattern.
+               PatternSegment(DataSource & source, uint32_t pattern);
+
+               //! \name Segment methods
+               //@{
+               //! \brief Pattern segments have no natural address.
+               virtual bool hasNaturalLocation() { return false; }
+               
+               //! \brief Performs a pattern fill into the \a buffer.
+               virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
+               
+               //! \brief Returns a length based on the data target's address range.
+               virtual unsigned getLength();
+               //@}
+               
+               //! \name Pattern accessors
+               //@{
+               //! \brief Assigns a new fill pattern.
+               inline void setPattern(const SizedIntegerValue & newPattern) { m_pattern = newPattern; }
+               
+               //! \brief Return the fill pattern for the segment.
+               inline SizedIntegerValue & getPattern() { return m_pattern; }
+       
+               //! \brief Assignment operator, sets the pattern value and length.
+               PatternSegment & operator = (const SizedIntegerValue & value) { m_pattern = value; return *this; }
+               //@}
+               
+       protected:
+               SizedIntegerValue m_pattern;    //!< The fill pattern.
+       };
+       
+public:
+       //! \brief Default constructor.
+       DataSource() : m_target(0) {}
+       
+       //! \brief Destructor.
+       virtual ~DataSource() {}
+       
+       //! \name Data target
+       //@{
+       //! \brief Sets the associated data target.
+       inline void setTarget(DataTarget * target) { m_target = target; }
+       
+       //! \brief Gets the associated data target.
+       inline DataTarget * getTarget() const { return m_target; }
+       //@}
+       
+       //! \name Segments
+       //@{
+       //! \brief Returns the number of segments in this data source.
+       virtual unsigned getSegmentCount()=0;
+       
+       //! \brief Returns segment number \a index of the data source.
+       virtual Segment * getSegmentAt(unsigned index)=0;
+       //@}
+       
+protected:
+       DataTarget * m_target;  //!< Corresponding target for this source.
+};
+
+/*!
+ * \brief Data source for a repeating pattern.
+ *
+ * The pattern is represented by a SizedIntegerValue object. Thus the pattern
+ * can be either byte, half-word, or word sized.
+ *
+ * This data source has only one segment, and the PatternSource instance acts
+ * as its own single segment.
+ */
+class PatternSource : public DataSource, public DataSource::PatternSegment
+{
+public:
+       //! \brief Default constructor.
+       PatternSource();
+       
+       //! \brief Constructor taking the pattern value.
+       PatternSource(const SizedIntegerValue & value);
+       
+       //! \brief There is only one segment.
+       virtual unsigned getSegmentCount() { return 1; }
+       
+       //! \brief Returns this object, as it is its own segment.
+       virtual DataSource::Segment * getSegmentAt(unsigned index) { return this; }
+       
+       //! \brief Assignment operator, sets the pattern value and length.
+       PatternSource & operator = (const SizedIntegerValue & value) { setPattern(value); return *this; }
+};
+
+/*!
+ * \brief Data source for data that is not memory mapped (has no natural address).
+ *
+ * This data source can only manage a single block of data, which has no
+ * associated address. It acts as its own Segment.
+ */
+class UnmappedDataSource : public DataSource, public DataSource::Segment
+{
+public:
+       //! \brief Default constructor.
+       UnmappedDataSource();
+       
+       //! \brief Constructor taking the data, which is copied.
+       UnmappedDataSource(const uint8_t * data, unsigned length);
+       
+       //! \brief Sets the source's data.
+       void setData(const uint8_t * data, unsigned length);
+       
+       //! \brief There is only one segment.
+       virtual unsigned getSegmentCount() { return 1; }
+       
+       //! \brief Returns this object, as it is its own segment.
+       virtual DataSource::Segment * getSegmentAt(unsigned index) { return this; }
+               
+       //! \name Segment methods
+       //@{
+       //! \brief Unmapped data sources have no natural address.
+       virtual bool hasNaturalLocation() { return false; }
+       
+       //! \brief Copies a portion of the data into \a buffer.
+       virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
+       
+       //! \brief Returns the number of bytes of data managed by the source.
+       virtual unsigned getLength() { return m_length; }
+       //@}
+
+protected:
+       smart_array_ptr<uint8_t> m_data;        //!< The data.
+       unsigned m_length;      //!< Byte count of the data.
+};
+
+/*!
+ * \brief Data source that takes its data from an executable image.
+ *
+ * \see StExecutableImage
+ */
+class MemoryImageDataSource : public DataSource
+{
+public:
+       //! \brief Default constructor.
+       MemoryImageDataSource(StExecutableImage * image);
+       
+       //! \brief Destructor.
+       virtual ~MemoryImageDataSource();
+       
+       //! \brief Returns the number of memory regions in the image.
+       virtual unsigned getSegmentCount();
+       
+       //! \brief Returns the data source segment at position \a index.
+       virtual DataSource::Segment * getSegmentAt(unsigned index);
+       
+protected:
+       /*!
+        * \brief Segment corresponding to a text region of the executable image.
+        */
+       class TextSegment : public DataSource::Segment
+       {
+       public:
+               //! \brief Default constructor
+               TextSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index);
+               
+               virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
+               virtual unsigned getLength();
+       
+               virtual bool hasNaturalLocation() { return true; }
+               virtual uint32_t getBaseAddress();
+       
+       protected:
+               StExecutableImage * m_image;    //!< Coalesced image of the file.
+               unsigned m_index;       //!< Record index.
+       };
+       
+       /*!
+        * \brief Segment corresponding to a fill region of the executable image.
+        */
+       class FillSegment : public DataSource::PatternSegment
+       {
+       public:
+               FillSegment(MemoryImageDataSource & source, StExecutableImage * image, unsigned index);
+               
+               virtual unsigned getLength();
+       
+               virtual bool hasNaturalLocation() { return true; }
+               virtual uint32_t getBaseAddress();
+       
+       protected:
+               StExecutableImage * m_image;    //!< Coalesced image of the file.
+               unsigned m_index;       //!< Record index.
+       };
+       
+protected:
+       StExecutableImage * m_image;    //!< The memory image that is the data source.
+       
+       typedef std::vector<DataSource::Segment*> segment_array_t;      //!< An array of segments.
+       segment_array_t m_segments;     //!< The array of Segment instances.
+};
+
+}; // namespace elftosb
+
+#endif // _DataSource_h_
diff --git a/tools/elftosb/common/DataSourceImager.cpp b/tools/elftosb/common/DataSourceImager.cpp
new file mode 100644 (file)
index 0000000..14a9307
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * File:       DataSourceImager.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "DataSourceImager.h"
+#include <stdlib.h>
+#include <string.h>
+
+using namespace elftosb;
+
+DataSourceImager::DataSourceImager()
+:      Blob(),
+       m_fill(0),
+       m_baseAddress(0),
+       m_isBaseAddressSet(false)
+{
+}
+
+void DataSourceImager::setBaseAddress(uint32_t address)
+{
+       m_baseAddress = address;
+       m_isBaseAddressSet = true;
+}
+
+void DataSourceImager::setFillPattern(uint8_t pattern)
+{
+       m_fill = pattern;
+}
+
+void DataSourceImager::reset()
+{
+       clear();
+       
+       m_fill = 0;
+       m_baseAddress = 0;
+       m_isBaseAddressSet = false;
+}
+
+//! \param dataSource Pointer to an instance of a concrete data source subclass.
+//!
+void DataSourceImager::addDataSource(DataSource * source)
+{
+       unsigned segmentCount = source->getSegmentCount();
+       unsigned index = 0;
+       for (; index < segmentCount; ++index)
+       {
+               addDataSegment(source->getSegmentAt(index));
+       }
+}
+
+//! \param segment The segment to add. May be any type of data segment, including
+//!            a pattern segment.
+void DataSourceImager::addDataSegment(DataSource::Segment * segment)
+{
+       DataSource::PatternSegment * patternSegment = dynamic_cast<DataSource::PatternSegment*>(segment);
+       
+       unsigned segmentLength = segment->getLength();
+       bool segmentHasLocation = segment->hasNaturalLocation();
+       uint32_t segmentAddress = segment->getBaseAddress();
+       
+       uint8_t * toPtr = NULL;
+       unsigned addressDelta;
+       unsigned newLength;
+       
+       // If a pattern segment's length is 0 then make it as big as the fill pattern.
+       // This needs to be done before the buffer is adjusted.
+       if (patternSegment && segmentLength == 0)
+       {
+               SizedIntegerValue & pattern = patternSegment->getPattern();
+               segmentLength = pattern.getSize();
+       }
+       
+       if (segmentLength)
+       {
+               if (segmentHasLocation)
+               {
+                       // Make sure a base address is set.
+                       if (!m_isBaseAddressSet)
+                       {
+                               m_baseAddress = segmentAddress;
+                               m_isBaseAddressSet = true;
+                       }
+                       
+                       // The segment is located before our buffer's first address.
+                       // toPtr is not set in this if, but in the else branch of the next if.
+                       // Unless the segment completely overwrite the current data.
+                       if (segmentAddress < m_baseAddress)
+                       {
+                               addressDelta = m_baseAddress - segmentAddress;
+                               
+                               uint8_t * newData = (uint8_t *)malloc(m_length + addressDelta);
+                               memcpy(&newData[addressDelta], m_data, m_length);
+                               free(m_data);
+                               
+                               m_data = newData;
+                               m_length += addressDelta;
+                               m_baseAddress = segmentAddress;
+                       }
+                       
+                       // This segment is located or extends outside of our buffer.
+                       if (segmentAddress + segmentLength > m_baseAddress + m_length)
+                       {
+                               newLength = segmentAddress + segmentLength - m_baseAddress;
+                               
+                               m_data = (uint8_t *)realloc(m_data, newLength);
+                               
+                               // Clear any bytes between the old data and the new segment.
+                               addressDelta = segmentAddress - (m_baseAddress + m_length);
+                               if (addressDelta)
+                               {
+                                       memset(m_data + m_length, 0, addressDelta);
+                               }
+                               
+                               toPtr = m_data + (segmentAddress - m_baseAddress);
+                               m_length = newLength;
+                       }
+                       else
+                       {
+                               toPtr = m_data + (segmentAddress - m_baseAddress);
+                       }
+               }
+               // Segment has no natural location, so just append it to the end of our buffer.
+               else
+               {
+                       newLength = m_length + segmentLength;
+                       m_data = (uint8_t *)realloc(m_data, newLength);
+                       toPtr = m_data + m_length;
+                       m_length = newLength;
+               }
+       }
+
+       // A loop is used because getData() may fill in less than the requested
+       // number of bytes per call.
+       unsigned offset = 0;
+       while (offset < segmentLength)
+       {
+               offset += segment->getData(offset, segmentLength - offset, toPtr + offset);
+       }
+}
+
diff --git a/tools/elftosb/common/DataSourceImager.h b/tools/elftosb/common/DataSourceImager.h
new file mode 100644 (file)
index 0000000..00e61df
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * File:       DataSourceImager.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_DataSourceImager_h_)
+#define _DataSourceImager_h_
+
+#include "Blob.h"
+#include "DataSource.h"
+
+namespace elftosb {
+
+/*!
+ * \brief Converts a DataSource into a single binary buffer.
+ */
+class DataSourceImager : public Blob
+{
+public:
+       //! \brief Constructor.
+       DataSourceImager();
+       
+       //! \name Setup
+       //@{
+       void setBaseAddress(uint32_t address);
+       void setFillPattern(uint8_t pattern);
+       //@}
+       
+       void reset();
+       
+       //! \name Accessors
+       //@{
+       uint32_t getBaseAddress() { return m_baseAddress; }
+       //@}
+       
+       //! \name Operations
+       //@{
+       //! \brief Adds all of the segments of which \a dataSource is composed.
+       void addDataSource(DataSource * source);
+       
+       //! \brief Adds the data from one data segment.
+       void addDataSegment(DataSource::Segment * segment);
+       //@}
+
+protected:
+       uint8_t m_fill;
+       uint32_t m_baseAddress;
+       bool m_isBaseAddressSet;
+};
+
+};
+
+#endif // _DataSourceImager_h_
diff --git a/tools/elftosb/common/DataTarget.cpp b/tools/elftosb/common/DataTarget.cpp
new file mode 100644 (file)
index 0000000..aab2c7b
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * File:       DataTarget.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "DataTarget.h"
+#include "DataSource.h"
+#include "ElftosbErrors.h"
+
+using namespace elftosb;
+
+//! \exception elftosb::semantic_error Thrown if the source has multiple segments.
+DataTarget::AddressRange ConstantDataTarget::getRangeForSegment(DataSource & source, DataSource::Segment & segment)
+{
+       // can't handle multi-segment data sources
+       if (source.getSegmentCount() > 1)
+       {
+               throw semantic_error("constant targets only support single-segment sources");
+       }
+       
+       // always relocate the segment to our begin address
+       AddressRange range;
+       range.m_begin = m_begin;
+       
+       if (isBounded())
+       {
+               // we have an end address. trim the result range to the segment size
+               // or let the end address crop the segment.
+               range.m_end = std::min<uint32_t>(m_end, m_begin + segment.getLength());
+       }
+       else
+       {
+               // we have no end address, so the segment size determines it.
+               range.m_end = m_begin + segment.getLength();
+       }
+       
+       return range;
+}
+
+//! If the \a segment has a natural location, the returned address range extends
+//! from the segment's base address to its base address plus its length.
+//!
+//! \exception elftosb::semantic_error This exception is thrown if the \a segment
+//!            does not have a natural location associated with it.
+DataTarget::AddressRange NaturalDataTarget::getRangeForSegment(DataSource & source, DataSource::Segment & segment)
+{
+       if (!segment.hasNaturalLocation())
+       {
+               throw semantic_error("source has no natural location");
+       }
+       
+       AddressRange range;
+       range.m_begin = segment.getBaseAddress();
+       range.m_end = segment.getBaseAddress() + segment.getLength();
+       return range;
+}
+
diff --git a/tools/elftosb/common/DataTarget.h b/tools/elftosb/common/DataTarget.h
new file mode 100644 (file)
index 0000000..e154491
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * File:       DataTarget.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_DataTarget_h_)
+#define _DataTarget_h_
+
+#include "stdafx.h"
+#include "DataSource.h"
+
+namespace elftosb
+{
+
+// Forward declaration
+class DataSource;
+
+/*!
+ * \brief Abstract base class for the target address or range of data.
+ *
+ * Targets at the most basic level have a single address, and potentially
+ * an address range. Unbounded targets have a beginning address but no
+ * specific end address, while bounded targets do have an end address.
+ *
+ * Users of a data target can access the begin and end addresses directly.
+ * However, the most powerful way to use a target is with the
+ * getRangeForSegment() method. This method returns the target address range
+ * for a segment of a data source. The value of the resulting range can be
+ * completely dependent upon the segment's properties, those of its data
+ * source, and the type of data target.
+ *
+ * \see elftosb::DataSource
+ */
+class DataTarget
+{
+public:
+       //! \brief Simple structure that describes an addressed region of memory.
+       //! \todo Decide if the end address is inclusive or not.
+       struct AddressRange
+       {
+               uint32_t m_begin;
+               uint32_t m_end;
+       };
+       
+public:
+       //! \brief Default constructor.
+       DataTarget() : m_source(0) {}
+       
+       //! \brief Destructor.
+       virtual ~DataTarget() {}
+       
+       //! \brief Whether the target is just a single address or has an end to it.
+       virtual bool isBounded() { return false; }
+       
+       virtual uint32_t getBeginAddress() { return 0; }
+       virtual uint32_t getEndAddress() { return 0; }
+       
+       //! \brief Return the address range for a segment of a data source.
+       virtual DataTarget::AddressRange getRangeForSegment(DataSource & source, DataSource::Segment & segment)=0;
+       
+       inline void setSource(DataSource * source) { m_source = source; }
+       inline DataSource * getSource() const { return m_source; }
+       
+protected:
+       DataSource * m_source;  //!< Corresponding data source for this target.
+};
+
+/*!
+ * \brief Target with a constant values for the addresses.
+ *
+ * This target type supports can be both bounded and unbounded. It always has
+ * at least one address, the beginning address. The end address is optional,
+ * and if not provided makes the target unbounded.
+ */
+class ConstantDataTarget : public DataTarget
+{
+public:
+       //! \brief Constructor taking only a begin address.
+       ConstantDataTarget(uint32_t start) : DataTarget(), m_begin(start), m_end(0), m_hasEnd(false) {}
+       
+       //! \brief Constructor taking both begin and end addresses.
+       ConstantDataTarget(uint32_t start, uint32_t end) : DataTarget(), m_begin(start), m_end(end), m_hasEnd(true) {}
+       
+       //! \brief The target is bounded if an end address was specified.
+       virtual bool isBounded() { return m_hasEnd; }
+       
+       virtual uint32_t getBeginAddress() { return m_begin; }
+       virtual uint32_t getEndAddress() { return m_end; }
+       
+       //! \brief Return the address range for a segment of a data source.
+       virtual DataTarget::AddressRange getRangeForSegment(DataSource & source, DataSource::Segment & segment);
+       
+protected:
+       uint32_t m_begin;       //!< Start address.
+       uint32_t m_end;         //!< End address.
+       bool m_hasEnd;          //!< Was an end address specified?
+};
+
+/*!
+ * \brief Target address that is the "natural" location of whatever the source data is.
+ *
+ * The data source used with the target must have a natural location. If
+ * getRangeForSegment() is called with a segment that does not have a natural
+ * location, a semantic_error will be thrown.
+ */
+class NaturalDataTarget : public DataTarget
+{
+public:
+       //! \brief Default constructor.
+       NaturalDataTarget() : DataTarget() {}
+       
+       //! \brief Natural data targets are bounded by their source's segment lengths.
+       virtual bool isBounded() { return true; }
+       
+       //! \brief Return the address range for a segment of a data source.
+       virtual DataTarget::AddressRange getRangeForSegment(DataSource & source, DataSource::Segment & segment);
+};
+
+}; // namespace elftosb
+
+#endif // _DataTarget_h_
diff --git a/tools/elftosb/common/ELF.h b/tools/elftosb/common/ELF.h
new file mode 100644 (file)
index 0000000..f477610
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * File:       ELF.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_ELF_h_)
+#define _ELF_h_
+
+//! \name ELF types
+//! Types used in ELF file structures.
+//@{
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef /*off_t*/ uint32_t Elf32_Off;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+//@}
+
+// All ELF structures are byte aligned. Any alignment padding is explicit.
+#pragma pack(1)
+
+//! \name File header
+//@{
+
+/*!
+ * Constants for the various fields of Elf32_Ehdr.e_ident.
+ */
+enum {
+       EI_MAG0 = 0,
+       EI_MAG1,
+       EI_MAG2,
+       EI_MAG3,
+       EI_CLASS,
+       EI_DATA,
+       EI_VERSION,
+       EI_PAD,
+       EI_NIDENT = 16,
+       
+       // Magic number.
+       ELFMAG0 = 0x7f,
+       ELFMAG1 = 'E',
+       ELFMAG2 = 'L',
+       ELFMAG3 = 'F',
+       
+       // EI_CLASS
+       ELFCLASSNONE = 0,
+       ELFCLASS32 = 1,
+       ELFCLASS64 = 2,
+       
+       // EI_DATA
+       ELFDATANONE = 0,
+       ELFDATA2LSB = 1,
+       ELFDATA2MSB = 2
+};
+
+/*!
+ * \brief ELF file header.
+ */
+struct Elf32_Ehdr
+{
+       unsigned char e_ident[EI_NIDENT];       //!< Magic number identifying the file format.
+       Elf32_Half e_type;              //!< Identifies the object file format.
+       Elf32_Half e_machine;   //!< Specified the architecture for the object file.
+       Elf32_Word e_version;   //!< Object file version.
+       Elf32_Addr e_entry;             //!< Virtual address of the entry point, or 0.
+       Elf32_Off e_phoff;              //!< Program header table offset in bytes, or 0 if no program header table.
+       Elf32_Off e_shoff;              //!< Section header table offset in bytes, or 0 if no section header table.
+       Elf32_Word e_flags;             //!< Processor-specific flags associated with the file.
+       Elf32_Half e_ehsize;    //!< The ELF header's size in bytes.
+       Elf32_Half e_phentsize; //!< Size in bytes of one entry in the program header table.
+       Elf32_Half e_phnum;             //!< Number of entries in the program header table.
+       Elf32_Half e_shentsize; //!< Size in bytes of an entry in the section header table.
+       Elf32_Half e_shnum;             //!< Number of entries in the section header table.
+       Elf32_Half e_shstrndx;  //!< Section header table index of the section name string table.
+};
+
+/*!
+ * Constants for #Elf32_Ehdr.e_type.
+ */
+enum {
+       ET_NONE,        //!< No file type.
+       ET_REL,         //!< Relocatable file.
+       ET_EXEC,        //!< Executable file.
+       ET_DYN,         //!< Shared object file.
+       ET_CORE,        //!< Core file.
+       ET_LOPROC,      //!< Low bound of processor-specific file types.
+       ET_HIPROC       //!< High bound of processor-specific file types.
+};     
+
+/*!
+ * ARM-specific #Elf32_Ehdr.e_flags
+ */
+enum {
+       EF_ARM_HASENTRY = 0x02,                 //!< #Elf32_Ehdr.e_entry contains a program-loader entry point.
+       EF_ARM_SYMSARESORTED = 0x04,    //!< Each subsection of the symbol table is sorted by symbol value.
+       EF_ARM_DYNSYMSUSESEGIDX = 0x08, //!< Symbols in dynamic symbol tables that are defined in sections included in program segment n have #Elf32_Sym.st_shndx = n + 1.
+       EF_ARM_MAPSYMSFIRST = 0x10,             //!< Mapping symbols precede other local symbols in the symbol table.
+       EF_ARM_EABIMASK = 0xff000000,   //!< This masks an 8-bit version number, the version of the ARM EABI to which this ELF file conforms. The current EABI version is #ARM_EABI_VERSION.
+       
+       ARM_EABI_VERSION = 0x02000000   //!< Current ARM EABI version.
+};
+
+//@}
+
+//! \name Sections
+//@{
+
+/*!
+ * \brief ELF section header.
+ *
+ * An object file's section header table lets one locate all the file's
+ * sections. The section header table is an array of #Elf32_Shdr structures.
+ * A section header table index is a subscript into this array. The ELF
+ * header's #Elf32_Ehdr::e_shoff member gives the byte offset from the beginning of
+ * the file to the section header table; #Elf32_Ehdr::e_shnum tells how many entries
+ * the section header table contains; #Elf32_Ehdr::e_shentsize gives the size in bytes
+ * of each entry.
+ *
+ * Some section header table indexes are reserved. An object file will not
+ * have sections for these special indexes:
+ *  - #SHN_UNDEF
+ *  - #SHN_LORESERVE
+ *  - #SHN_LOPROC
+ *  - #SHN_HIPROC
+ *  - #SHN_ABS
+ *  - #SHN_COMMON
+ *  - #SHN_HIRESERVE
+ */
+struct Elf32_Shdr
+{
+       Elf32_Word sh_name;             //!< The section's name. Index into the section header string table section.
+       Elf32_Word sh_type;             //!< Section type, describing the contents and semantics.
+       Elf32_Word sh_flags;    //!< Section flags describing various attributes.
+       Elf32_Addr sh_addr;             //!< The address at which the section will appear in the memory image, or 0.
+       Elf32_Off sh_offset;    //!< Offset from beginning of the file to the first byte in the section.
+       Elf32_Word sh_size;             //!< The section's size in bytes.
+       Elf32_Word sh_link;             //!< Section header table link index. Interpretation depends on section type.
+       Elf32_Word sh_info;             //!< Extra information about the section. Depends on section type.
+       Elf32_Word sh_addralign;        //!< Address alignment constraint. Values are 0 and positive powers of 2.
+       Elf32_Word sh_entsize;  //!< Size in bytes of section entries, or 0 if the section does not have fixed-size entries.
+};
+
+/*!
+ * Special section indexes.
+ */
+enum {
+       SHN_UNDEF = 0,
+       SHN_LORESERVE = 0xff00,
+       SHN_LOPROC = 0xff00,
+       SHN_HIPROC = 0xff1f,
+       SHN_ABS = 0xfff1,               //!< The symbol has an absolute value that will not change because of relocation.
+       SHN_COMMON = 0xfff2,    //!< The symbol labels a common block that has not yet been allocated.
+       SHN_HIRESERVE = 0xffff
+};
+
+/*!
+ * Section type constants.
+ */
+enum {
+       SHT_NULL = 0,
+       SHT_PROGBITS = 1,
+       SHT_SYMTAB = 2,
+       SHT_STRTAB = 3,
+       SHT_RELA = 4,
+       SHT_HASH = 5,
+       SHT_DYNAMIC = 6,
+       SHT_NOTE = 7,
+       SHT_NOBITS = 8,
+       SHT_REL = 9,
+       SHT_SHLIB = 10,
+       SHT_DYNSYM = 11
+};
+
+/*!
+ * Section flag constants.
+ */
+enum {
+       SHF_WRITE = 0x1,        //!< Section is writable.
+       SHF_ALLOC = 0x2,        //!< Allocate section.
+       SHF_EXECINSTR = 0x4     //!< Section contains executable instructions.
+};
+
+/*!
+ * ARM-specific section flag constants
+ */
+enum {
+       SHF_ENTRYSECT = 0x10000000,     //!< The section contains an entry point.
+       SHF_COMDEF = 0x80000000         //!< The section may be multiply defined in the input to a link step.
+};
+
+#define BSS_SECTION_NAME ".bss"
+#define DATA_SECTION_NAME ".data"
+#define TEXT_SECTION_NAME ".text"
+#define SHSTRTAB_SECTION_NAME ".shstrtab"
+#define STRTAB_SECTION_NAME ".strtab"
+#define SYMTAB_SECTION_NAME ".symtab"
+
+//@}
+
+//! \name Segments
+//@{
+
+/*!
+ * \brief ELF program header.
+ *
+ * An executable or shared object file's program header table is an array of
+ * structures, each describing a segment or other information the system needs
+ * to prepare the program for execution. An object file segment contains one
+ * or more sections. Program headers are meaningful only for executable and
+ * shared object files. A file specifies its own program header size with the
+ * ELF header's #Elf32_Ehdr::e_phentsize and #Elf32_Ehdr::e_phnum members.
+ */
+struct Elf32_Phdr
+{
+       Elf32_Word p_type;              //!< What type of segment this header describes.
+       Elf32_Off p_offset;             //!< Offset in bytes from start of file to the first byte of the segment.
+       Elf32_Addr p_vaddr;             //!< Virtual address at which the segment will reside in memory.
+       Elf32_Addr p_paddr;             //!< Physical address, for systems where this is relevant.
+       Elf32_Word p_filesz;    //!< Number of bytes of file data the segment consumes. May be zero.
+       Elf32_Word p_memsz;             //!< Size in bytes of the segment in memory. May be zero.
+       Elf32_Word p_flags;             //!< Flags relevant to the segment.
+       Elf32_Word p_align;             //!< Alignment constraint for segment addresses. Possible values are 0 and positive powers of 2.
+};
+
+/*!
+ * Segment type constants.
+ */
+enum {
+       PT_NULL = 0,
+       PT_LOAD = 1,
+       PT_DYNAMIC = 2,
+       PT_INTERP = 3,
+       PT_NOTE = 4,
+       PT_SHLIB = 5,
+       PT_PHDR = 6
+};
+
+/*!
+ * Program header flag constants.
+ */
+enum {
+       PF_X = 0x1,     //!< Segment is executable.
+       PF_W = 0x2,     //!< Segment is writable.
+       PF_R = 0x4      //!< Segment is readable.
+};
+
+//@}
+
+//! \name Symbol table
+//@{
+
+enum {
+       STN_UNDEF = 0   //!< Undefined symbol index.
+};
+
+/*!
+ * \brief ELF symbol table entry.
+ *
+ * An object file's symbol table holds information needed to locate and
+ * relocate a program's symbolic definitions and references. A symbol
+ * table index is a subscript into this array. Index 0 both designates
+ * the first entry in the table and serves as the undefined symbol index.
+ */
+struct Elf32_Sym
+{
+       Elf32_Word st_name;             //!< Index into file's string table.
+       Elf32_Addr st_value;    //!< Value associated with the symbol. Depends on context.
+       Elf32_Word st_size;             //!< Size associated with symbol. 0 if the symbol has no size or an unknown size.
+       unsigned char st_info;  //!< Specified the symbol's type and binding attributes.
+       unsigned char st_other; //!< Currently 0 (reserved).
+       Elf32_Half st_shndx;    //!< Section header table index for this symbol.
+};
+
+//! \name st_info macros
+//! Macros for manipulating the st_info field of Elf32_Sym struct.
+//@{
+#define ELF32_ST_BIND(i) ((i) >> 4)                    //!< Get binding attributes.
+#define ELF32_ST_TYPE(i) ((i) & 0x0f)          //!< Get symbol type.
+#define ELF32_ST_INFO(b, t) (((b) << 4) + ((t) & 0x0f))        //!< Construct st_info value from binding attributes and symbol type.
+//@}
+
+/*!
+ * \brief Symbol binding attributes.
+ *
+ * These constants are mask values.
+ */
+enum {
+       STB_LOCAL = 0,  //!< Local symbol not visible outside the object file.
+       STB_GLOBAL = 1, //!< Symbol is visible to all object files being linked together.
+       STB_WEAK = 2,   //!< Like global symbols, but with lower precedence.
+       
+       // Processor-specific semantics.
+       STB_LOPROC = 13,
+       STB_HIPROC = 15
+};
+
+/*!
+ * \brief Symbol types.
+ */
+enum {
+       STT_NOTYPE = 0,         //!< The symbol's type is not specified.
+       STT_OBJECT = 1,         //!< The symbol is associated with a data object, such as a variable or array.
+       STT_FUNC = 2,           //!< The symbol is associated with a function or other executable code.
+       STT_SECTION = 3,        //!< The synmbol is associated with a section. Primarily used for relocation.
+       STT_FILE = 4,           //!< A file symbol has STB_LOCAL binding, its section index is SHN_ABS, and it precedes the other STB_LOCAL symbols for the file, if it is present.
+       
+       STT_LOPROC = 13,        //!< Low bound of processor-specific symbol types.
+       STT_HIPROC = 15         //!< High bound of processor-specific symbol types.
+};
+
+/*!
+ * GHS-specific constants
+ */
+enum {
+       STO_THUMB = 1   //!< This flag is set on #Elf32_Sym.st_other if the symbol is Thumb mode code.
+};
+
+#define ARM_SEQUENCE_MAPSYM "$a"
+#define DATA_SEQUENCE_MAPSYM "$d"
+#define THUMB_SEQUENCE_MAPSYM "$t"
+
+#define THUMB_BL_TAGSYM "$b"
+#define FN_PTR_CONST_TAGSYM "$f"
+#define INDIRECT_FN_CALL_TAGSYM "$p"
+#define MAPPING_SYMBOL_COUNT_TAGSYM "$m"
+
+//@}
+
+#pragma pack()
+
+#endif // _ELF_h_
diff --git a/tools/elftosb/common/ELFSourceFile.cpp b/tools/elftosb/common/ELFSourceFile.cpp
new file mode 100644 (file)
index 0000000..962256a
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+ * File:       ELFSourceFile.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "ELFSourceFile.h"
+#include "Logging.h"
+#include "GHSSecInfo.h"
+#include <ctype.h>
+#include <algorithm>
+#include "string.h"
+
+//! The name of the toolset option.
+#define kToolsetOptionName "toolset"
+#define kGHSToolsetName "GHS"
+#define kGCCToolsetName "GCC"
+#define kGNUToolsetName "GNU"
+#define kADSToolsetName "ADS"
+
+//! Name of the option to control .secinfo action.
+#define kSecinfoClearOptionName "secinfoClear"
+#define kSecinfoDefaultName "DEFAULT"
+#define kSecinfoIgnoreName "IGNORE"
+#define kSecinfoROMName "ROM"
+#define kSecinfoCName "C"
+
+using namespace elftosb;
+
+ELFSourceFile::ELFSourceFile(const std::string & path)
+:      SourceFile(path),
+       m_toolset(kUnknownToolset),
+       m_secinfoOption(kSecinfoDefault)
+{
+}
+
+ELFSourceFile::~ELFSourceFile()
+{
+}
+
+bool ELFSourceFile::isELFFile(std::istream & stream)
+{
+       try
+       {
+               StELFFile elf(stream);
+               return true;
+       }
+       catch (...)
+       {
+               return false;
+       }
+}
+
+void ELFSourceFile::open()
+{
+       // Read toolset option
+       m_toolset = readToolsetOption();
+
+       // Read option and select default value
+       m_secinfoOption = readSecinfoClearOption();
+       if (m_secinfoOption == kSecinfoDefault)
+       {
+               m_secinfoOption = kSecinfoCStartupClear;
+       }
+       
+       // Open the stream
+       SourceFile::open();
+       
+       m_file = new StELFFile(*m_stream);
+//     m_file->dumpSections();
+       
+       // Set toolset in elf file object
+       switch (m_toolset)
+       {
+        // default toolset is GHS
+               case kGHSToolset:
+        case kUnknownToolset:
+                       m_file->setELFVariant(eGHSVariant);
+                       break;
+               case kGCCToolset:
+                       m_file->setELFVariant(eGCCVariant);
+                       break;
+               case kADSToolset:
+                       m_file->setELFVariant(eARMVariant);
+                       break;
+       }
+}
+
+void ELFSourceFile::close()
+{
+       SourceFile::close();
+       
+       m_file.safe_delete();
+}
+
+elf_toolset_t ELFSourceFile::readToolsetOption()
+{
+       do {
+               const OptionContext * options = getOptions();
+               if (!options || !options->hasOption(kToolsetOptionName))
+               {
+                       break;
+               }
+               
+               const Value * value = options->getOption(kToolsetOptionName);
+               const StringValue * stringValue = dynamic_cast<const StringValue*>(value);
+               if (!stringValue)
+               {
+                       // Not a string value, warn the user.
+                       Log::log(Logger::WARNING, "invalid type for 'toolset' option\n");
+                       break;
+               }
+               
+               std::string toolsetName = *stringValue;
+               
+               // convert option value to uppercase
+               std::transform<std::string::const_iterator, std::string::iterator, int (*)(int)>(toolsetName.begin(), toolsetName.end(), toolsetName.begin(), toupper);
+               
+               if (toolsetName == kGHSToolsetName)
+               {
+                       return kGHSToolset;
+               }
+               else if (toolsetName == kGCCToolsetName || toolsetName == kGNUToolsetName)
+               {
+                       return kGCCToolset;
+               }
+               else if (toolsetName == kADSToolsetName)
+               {
+                       return kADSToolset;
+               }
+
+               // Unrecognized option value, log a warning.
+               Log::log(Logger::WARNING, "unrecognized value for 'toolset' option\n");
+       } while (0);
+       
+       return kUnknownToolset;
+}
+
+//! It is up to the caller to convert from kSecinfoDefault to the actual default
+//! value.
+secinfo_clear_t ELFSourceFile::readSecinfoClearOption()
+{
+       do {
+               const OptionContext * options = getOptions();
+               if (!options || !options->hasOption(kSecinfoClearOptionName))
+               {
+                       break;
+               }
+               
+               const Value * value = options->getOption(kSecinfoClearOptionName);
+               const StringValue * stringValue = dynamic_cast<const StringValue*>(value);
+               if (!stringValue)
+               {
+                       // Not a string value, warn the user.
+                       Log::log(Logger::WARNING, "invalid type for 'secinfoClear' option\n");
+                       break;
+               }
+               
+               std::string secinfoOption = *stringValue;
+               
+               // convert option value to uppercase
+               std::transform<std::string::const_iterator, std::string::iterator, int (*)(int)>(secinfoOption.begin(), secinfoOption.end(), secinfoOption.begin(), toupper);
+               
+               if (secinfoOption == kSecinfoDefaultName)
+               {
+                       return kSecinfoDefault;
+               }
+               else if (secinfoOption == kSecinfoIgnoreName)
+               {
+                       return kSecinfoIgnore;
+               }
+               else if (secinfoOption == kSecinfoROMName)
+               {
+                       return kSecinfoROMClear;
+               }
+               else if (secinfoOption == kSecinfoCName)
+               {
+                       return kSecinfoCStartupClear;
+               }
+
+               // Unrecognized option value, log a warning.
+               Log::log(Logger::WARNING, "unrecognized value for 'secinfoClear' option\n");
+       } while (0);
+       
+       return kSecinfoDefault;
+}
+
+//! To create a data source for all sections of the ELF file, a WildcardMatcher
+//! is instantiated and passed to createDataSource(StringMatcher&).
+DataSource * ELFSourceFile::createDataSource()
+{
+       WildcardMatcher matcher;
+       return createDataSource(matcher);
+}
+       
+DataSource * ELFSourceFile::createDataSource(StringMatcher & matcher)
+{
+       assert(m_file);
+       ELFDataSource * source = new ELFDataSource(m_file);
+       source->setSecinfoOption(m_secinfoOption);
+       
+       Log::log(Logger::DEBUG2, "filtering sections of file: %s\n", getPath().c_str());
+       
+       // We start at section 1 to skip the null section that is always first.
+       unsigned index = 1;
+       for (; index < m_file->getSectionCount(); ++index)
+       {
+               const Elf32_Shdr & header = m_file->getSectionAtIndex(index);
+               std::string name = m_file->getSectionNameAtIndex(header.sh_name);
+               
+               // Ignore most section types
+               switch (header.sh_type) {
+               case SHT_PROGBITS:
+               case SHT_NOBITS:
+               case SHT_REL:
+               case SHT_DYNSYM:
+                       break;
+
+               default:
+                       continue;
+               }
+
+               // Ignore sections that don't have the allocate flag set.
+               if ((header.sh_flags & SHF_ALLOC) == 0)
+               {
+                       continue;
+               }
+
+               if (matcher.match(name))
+               {
+                       Log::log(Logger::DEBUG2, "creating segment for section %s\n", name.c_str());
+                       source->addSection(index);
+               }
+               else
+               {
+                       Log::log(Logger::DEBUG2, "section %s did not match\n", name.c_str());
+               }
+       }
+       
+       return source;
+}
+
+//! It is assumed that all ELF files have an entry point.
+//!
+bool ELFSourceFile::hasEntryPoint()
+{
+       return true;
+}
+
+//! The StELFFile::getTypeOfSymbolAtIndex() method uses different methods of determining
+//! ARM/Thumb mode depending on the toolset.
+uint32_t ELFSourceFile::getEntryPointAddress()
+{
+       uint32_t entryPoint = 0;
+       
+       // get entry point address
+       const Elf32_Ehdr & header = m_file->getFileHeader();
+
+       // find symbol corresponding to entry point and determine if
+       // it is arm or thumb mode
+       unsigned symbolIndex = m_file->getIndexOfSymbolAtAddress(header.e_entry);
+       if (symbolIndex != 0)
+       {
+               ARMSymbolType_t symbolType = m_file->getTypeOfSymbolAtIndex(symbolIndex);
+               bool entryPointIsThumb = (symbolType == eThumbSymbol);
+               const Elf32_Sym & symbol = m_file->getSymbolAtIndex(symbolIndex);
+               std::string symbolName = m_file->getSymbolName(symbol);
+
+               Log::log(Logger::DEBUG2, "Entry point is %s@0x%08x (%s)\n", symbolName.c_str(), symbol.st_value, entryPointIsThumb ? "Thumb" : "ARM");
+
+               // set entry point, setting the low bit if it is thumb mode
+               entryPoint = header.e_entry + (entryPointIsThumb ? 1 : 0);
+       }
+       else
+       {
+               entryPoint = header.e_entry;
+       }
+       
+       return entryPoint;
+}
+
+//! \return A DataTarget that describes the named section.
+//! \retval NULL There was no section with the requested name.
+DataTarget * ELFSourceFile::createDataTargetForSection(const std::string & section)
+{
+       assert(m_file);
+       unsigned index = m_file->getIndexOfSectionWithName(section);
+       if (index == SHN_UNDEF)
+       {
+               return NULL;
+       }
+       
+       const Elf32_Shdr & sectionHeader = m_file->getSectionAtIndex(index);
+       uint32_t beginAddress = sectionHeader.sh_addr;
+       uint32_t endAddress = beginAddress + sectionHeader.sh_size;
+       ConstantDataTarget * target = new ConstantDataTarget(beginAddress, endAddress);
+       return target;
+}
+
+//! \return A DataTarget instance pointing at the requested symbol.
+//! \retval NULL No symbol matching the requested name was found.
+DataTarget * ELFSourceFile::createDataTargetForSymbol(const std::string & symbol)
+{
+       assert(m_file);
+       unsigned symbolCount = m_file->getSymbolCount();
+       unsigned i;
+       
+       for (i=0; i < symbolCount; ++i)
+       {
+               const Elf32_Sym & symbolHeader = m_file->getSymbolAtIndex(i);
+               std::string symbolName = m_file->getSymbolName(symbolHeader);
+               if (symbolName == symbol)
+               {
+            ARMSymbolType_t symbolType = m_file->getTypeOfSymbolAtIndex(i);
+            bool symbolIsThumb = (symbolType == eThumbSymbol);
+            
+                       uint32_t beginAddress = symbolHeader.st_value + (symbolIsThumb ? 1 : 0);
+                       uint32_t endAddress = beginAddress + symbolHeader.st_size;
+                       ConstantDataTarget * target = new ConstantDataTarget(beginAddress, endAddress);
+                       return target;
+               }
+       }
+       
+       // didn't find a matching symbol
+       return NULL; 
+}
+
+bool ELFSourceFile::hasSymbol(const std::string & name)
+{
+       Elf32_Sym symbol;
+       return lookupSymbol(name, symbol);
+}
+
+uint32_t ELFSourceFile::getSymbolValue(const std::string & name)
+{
+       unsigned symbolCount = m_file->getSymbolCount();
+       unsigned i;
+       
+       for (i=0; i < symbolCount; ++i)
+       {
+               const Elf32_Sym & symbolHeader = m_file->getSymbolAtIndex(i);
+               std::string symbolName = m_file->getSymbolName(symbolHeader);
+               if (symbolName == name)
+               {
+            // If the symbol is a function, then we check to see if it is Thumb code and set bit 0 if so.
+            if (ELF32_ST_TYPE(symbolHeader.st_info) == STT_FUNC)
+            {
+                ARMSymbolType_t symbolType = m_file->getTypeOfSymbolAtIndex(i);
+                bool symbolIsThumb = (symbolType == eThumbSymbol);
+                return symbolHeader.st_value + (symbolIsThumb ? 1 : 0);
+            }
+            else
+            {
+                           return symbolHeader.st_value;
+            }
+               }
+       }
+       
+    // Couldn't find the symbol, so return 0.
+       return 0;
+}
+
+unsigned ELFSourceFile::getSymbolSize(const std::string & name)
+{
+       Elf32_Sym symbol;
+       if (!lookupSymbol(name, symbol))
+       {
+               return 0;
+       }
+       
+       return symbol.st_size;
+}
+
+//! \param name The name of the symbol on which info is wanted.
+//! \param[out] info Upon succssful return this is filled in with the symbol's information.
+//!
+//! \retval true The symbol was found and \a info is valid.
+//! \retval false No symbol with \a name was found in the file.
+bool ELFSourceFile::lookupSymbol(const std::string & name, Elf32_Sym & info)
+{
+       assert(m_file);
+       unsigned symbolCount = m_file->getSymbolCount();
+       unsigned i;
+       
+       for (i=0; i < symbolCount; ++i)
+       {
+               const Elf32_Sym & symbol = m_file->getSymbolAtIndex(i);
+               std::string thisSymbolName = m_file->getSymbolName(symbol);
+               
+               // Is this the symbol we're looking for?
+               if (thisSymbolName == name)
+               {
+                       info = symbol;
+                       return true;
+               }
+       }
+       
+       // Didn't file the symbol.
+       return false;
+}
+
+ELFSourceFile::ELFDataSource::~ELFDataSource()
+{
+       segment_vector_t::iterator it = m_segments.begin();
+       for (; it != m_segments.end(); ++it)
+       {
+               delete *it;
+       }
+}
+
+//! Not all sections will actually result in a new segment being created. Only
+//! those sections whose type is #SHT_PROGBITS or #SHT_NOBITS will create
+//! a new segment. Also, only sections whose size is non-zero will actually
+//! create a segment.
+//!
+//! In addition to this, ELF files that have been marked as being created by
+//! the Green Hills Software toolset have an extra step. #SHT_NOBITS sections
+//! are looked up in the .secinfo section to determine if they really
+//! should be filled. If not in the .secinfo table, no segment will be
+//! created for the section.
+void ELFSourceFile::ELFDataSource::addSection(unsigned sectionIndex)
+{
+       // get section info
+       const Elf32_Shdr & section = m_elf->getSectionAtIndex(sectionIndex);
+       if (section.sh_size == 0)
+       {
+               // empty section, so ignore it
+               return;
+       }
+       
+       // create the right segment subclass based on the section type
+       DataSource::Segment * segment = NULL;
+       switch (section.sh_type) {
+       case SHT_PROGBITS:
+       case SHT_REL:
+       case SHT_DYNSYM:
+               segment = new ProgBitsSegment(*this, m_elf, sectionIndex);
+               break;
+
+       case SHT_NOBITS:
+       {
+               // Always add NOBITS sections by default.
+               bool addNobits = true;
+
+               // For GHS ELF files, we use the secinfoClear option to figure out what to do.
+               // If set to ignore, treat like a normal ELF file and always add. If set to
+               // ROM, then only clear if the section is listed in .secinfo. Otherwise if set
+               // to C startup, then let the C startup do all clearing.
+               addNobits = false;
+               if (m_elf->ELFVariant() == eGHSVariant)
+               {
+                       GHSSecInfo secinfo(m_elf);
+
+                       // If there isn't a .secinfo section present then use the normal ELF rules
+                       // and always add NOBITS sections.
+                       if (secinfo.hasSecinfo() && m_secinfoOption != kSecinfoIgnore)
+                       {
+                               switch (m_secinfoOption)
+                               {
+                                       case kSecinfoROMClear:
+                                               addNobits = secinfo.isSectionFilled(section);
+                                               break;
+
+                                       case kSecinfoCStartupClear:
+                                               addNobits = false;
+                                               break;
+                               }
+                       }
+               }
+
+               if (addNobits)
+               {
+                       segment = new NoBitsSegment(*this, m_elf, sectionIndex);
+               }
+               else
+               {
+                       std::string name = m_elf->getSectionNameAtIndex(section.sh_name);
+                       Log::log(Logger::DEBUG2, "..section %s is not filled\n", name.c_str());
+               }
+       }
+       break;
+       }
+       // add segment if one was created
+       if (segment)
+       {
+               m_segments.push_back(segment);
+       }
+}
+
+ELFSourceFile::ELFDataSource::ProgBitsSegment::ProgBitsSegment(ELFDataSource & source, StELFFile * elf, unsigned index)
+:      DataSource::Segment(source), m_elf(elf), m_sectionIndex(index)
+{
+}
+
+unsigned ELFSourceFile::ELFDataSource::ProgBitsSegment::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)
+{
+       const Elf32_Shdr & section = m_elf->getSectionAtIndex(m_sectionIndex);
+       uint8_t * data = m_elf->getSectionDataAtIndex(m_sectionIndex);
+       
+       assert(offset < section.sh_size);
+       
+       unsigned copyBytes = std::min<unsigned>(section.sh_size - offset, maxBytes);
+       if (copyBytes)
+       {
+               memcpy(buffer, &data[offset], copyBytes);
+       }
+       
+       return copyBytes;
+}
+
+unsigned ELFSourceFile::ELFDataSource::ProgBitsSegment::getLength()
+{
+       const Elf32_Shdr & section = m_elf->getSectionAtIndex(m_sectionIndex);
+       return section.sh_size;
+}
+
+uint32_t ELFSourceFile::ELFDataSource::ProgBitsSegment::getBaseAddress()
+{
+       const Elf32_Shdr & section = m_elf->getSectionAtIndex(m_sectionIndex);
+       return section.sh_addr;
+}
+
+ELFSourceFile::ELFDataSource::NoBitsSegment::NoBitsSegment(ELFDataSource & source, StELFFile * elf, unsigned index)
+:      DataSource::PatternSegment(source), m_elf(elf), m_sectionIndex(index)
+{
+}
+
+unsigned ELFSourceFile::ELFDataSource::NoBitsSegment::getLength()
+{
+       const Elf32_Shdr & section = m_elf->getSectionAtIndex(m_sectionIndex);
+       return section.sh_size;
+}
+
+uint32_t ELFSourceFile::ELFDataSource::NoBitsSegment::getBaseAddress()
+{
+       const Elf32_Shdr & section = m_elf->getSectionAtIndex(m_sectionIndex);
+       return section.sh_addr;
+}
+
diff --git a/tools/elftosb/common/ELFSourceFile.h b/tools/elftosb/common/ELFSourceFile.h
new file mode 100644 (file)
index 0000000..c07aa56
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * File:       ELFSourceFile.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_ELFSourceFile_h_)
+#define _ELFSourceFile_h_
+
+#include "SourceFile.h"
+#include "StELFFile.h"
+#include "smart_ptr.h"
+#include "DataSource.h"
+#include "DataTarget.h"
+#include "ELF.h"
+
+namespace elftosb
+{
+
+//! Set of supported compiler toolsets.
+enum elf_toolset_t
+{
+       kUnknownToolset,        //!< Unknown.
+       kGHSToolset,            //!< Green Hills Software MULTI
+       kGCCToolset,            //!< GNU GCC
+       kADSToolset                     //!< ARM UK RealView
+};
+
+//! Options for handling the .secinfo section in GHS-produced ELF files.
+enum secinfo_clear_t
+{
+       // Default value for the .secinfo action.
+       kSecinfoDefault,
+
+       //! Ignore the .secinfo section if present. The standard ELF loading
+       //! rules are followed.
+       kSecinfoIgnore,
+
+       //! The boot ROM clears only those SHT_NOBITS sections present in .secinfo.
+       kSecinfoROMClear,
+       
+       //! The C startup is responsible for clearing sections. No fill commands
+       //! are generated for any SHT_NOBITS sections.
+       kSecinfoCStartupClear
+};
+
+/*!
+ * \brief Executable and Loading Format (ELF) source file.
+ */
+class ELFSourceFile : public SourceFile
+{
+public:
+       //! \brief Default constructor.
+       ELFSourceFile(const std::string & path);
+       
+       //! \brief Destructor.
+       virtual ~ELFSourceFile();
+       
+       //! \brief Identifies whether the stream contains an ELF file.
+       static bool isELFFile(std::istream & stream);
+       
+       //! \name Opening and closing
+       //@{
+       //! \brief Opens the file.
+       virtual void open();
+       
+       //! \brief Closes the file.
+       virtual void close();
+       //@}
+       
+       //! \name Format capabilities
+       //@{
+       virtual bool supportsNamedSections() const { return true; }
+       virtual bool supportsNamedSymbols() const { return true; }
+       //@}
+       
+       //! \name Data source
+       //@{
+       //! \brief Creates a data source from the entire file.
+       virtual DataSource * createDataSource();
+       
+       //! \brief Creates a data source from one or more sections of the file.
+       virtual DataSource * createDataSource(StringMatcher & matcher);
+       //@}
+       
+       //! \name Entry point
+       //@{
+       //! \brief Returns true if an entry point was set in the file.
+       virtual bool hasEntryPoint();
+       
+       //! \brief Returns the entry point address.
+       virtual uint32_t getEntryPointAddress();
+       //@}
+       
+       //! \name Data target
+       //@{
+       virtual DataTarget * createDataTargetForSection(const std::string & section);
+       virtual DataTarget * createDataTargetForSymbol(const std::string & symbol);
+       //@}
+       
+       //! \name Symbols
+       //@{
+       //! \brief Returns whether a symbol exists in the source file.
+       virtual bool hasSymbol(const std::string & name);
+       
+       //! \brief Returns the value of a symbol.
+       virtual uint32_t getSymbolValue(const std::string & name);
+       
+       //! \brief Returns the size of a symbol.
+       virtual unsigned getSymbolSize(const std::string & name);
+       //@}
+       
+       //! \name Direct ELF format access
+       //@{
+       //! \brief Returns the underlying StELFFile object.
+       StELFFile * getELFFile() { return m_file; }
+       
+       //! \brief Gets information about a symbol in the ELF file.
+       bool lookupSymbol(const std::string & name, Elf32_Sym & info);
+       //@}
+
+protected:
+       smart_ptr<StELFFile> m_file;    //!< Parser for the ELF file.
+       elf_toolset_t m_toolset;        //!< Toolset that produced the ELF file.
+       secinfo_clear_t m_secinfoOption;        //!< How to deal with the .secinfo section. Ignored if the toolset is not GHS.
+
+protected:
+       //! \brief Parses the toolset option value.
+       elf_toolset_t readToolsetOption();
+
+       //! \brief Reads the secinfoClear option.
+       secinfo_clear_t readSecinfoClearOption();
+       
+protected:
+       /*!
+        * \brief A data source with ELF file sections as the contents.
+        *
+        * Each segment of this data source corresponds directly with a named section
+        * of the ELF file it represents. When the data source is created, it contains
+        * no segments. Segments are created with the addSection() method, which takes
+        * the index of an ELF section and creates a corresponding segment.
+        *
+        * Two segment subclasses are used with this data source. The first, ProgBitsSegment,
+        * is used to represent sections whose type is #SHT_PROGBITS. These sections have
+        * binary data stored in the ELF file. The second segment type is NoBitsSegment.
+        * It is used to represent sections whose type is #SHT_NOBITS. These sections have
+        * no data, but simply allocate a region of memory to be filled with zeroes.
+        * As such, the NoBitsSegment class is a subclass of DataSource::PatternSegment.
+        */
+       class ELFDataSource : public DataSource
+       {
+       public:
+               /*!
+                * \brief Represents one named #SHT_PROGBITS section within the ELF file.
+                */
+               class ProgBitsSegment : public DataSource::Segment
+               {
+               public:
+                       ProgBitsSegment(ELFDataSource & source, StELFFile * elf, unsigned index);
+                       
+                       virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
+                       virtual unsigned getLength();
+               
+                       virtual bool hasNaturalLocation() { return true; }
+                       virtual uint32_t getBaseAddress();
+               
+               protected:
+                       StELFFile * m_elf;      //!< The format parser instance for this ELF file.
+                       unsigned m_sectionIndex;        //!< The index of the section this segment represents.
+               };
+               
+               /*!
+                * \brief Represents one named #SHT_NOBITS section within the ELF file.
+                *
+                * This segment class is a subclass of DataSource::PatternSegment since it
+                * represents a region of memory to be filled with zeroes.
+                */
+               class NoBitsSegment : public DataSource::PatternSegment
+               {
+               public:
+                       NoBitsSegment(ELFDataSource & source, StELFFile * elf, unsigned index);
+                       
+                       virtual unsigned getLength();
+               
+                       virtual bool hasNaturalLocation() { return true; }
+                       virtual uint32_t getBaseAddress();
+               
+               protected:
+                       StELFFile * m_elf;      //!< The format parser instance for this ELF file.
+                       unsigned m_sectionIndex;        //!< The index of the section this segment represents.
+               };
+               
+       public:
+               //! \brief Default constructor.
+               ELFDataSource(StELFFile * elf) : DataSource(), m_elf(elf) {}
+               
+               //! \brief Destructor.
+               virtual ~ELFDataSource();
+
+               //! Set the option to control .secinfo usage.
+               inline void setSecinfoOption(secinfo_clear_t option) { m_secinfoOption = option; }
+               
+               //! \brief Adds the ELF section at position \a sectionIndex to the data source.
+               void addSection(unsigned sectionIndex);
+               
+               //! \brief Returns the number of segments in the source.
+               virtual unsigned getSegmentCount() { return (unsigned)m_segments.size(); }
+               
+               //! \brief Returns the segment at position \a index.
+               virtual DataSource::Segment * getSegmentAt(unsigned index) { return m_segments[index]; }
+               
+       protected:
+               StELFFile * m_elf;      //!< The ELF file parser.
+               secinfo_clear_t m_secinfoOption;        //!< How to deal with the .secinfo section. Ignored if the toolset is not GHS.
+               
+               typedef std::vector<DataSource::Segment*> segment_vector_t;     //!< A list of segment instances.
+               segment_vector_t m_segments;    //!< The segments of this data source.
+       };
+
+};
+
+}; // namespace elftosb
+
+#endif // _ELFSourceFile_h_
diff --git a/tools/elftosb/common/EncoreBootImage.cpp b/tools/elftosb/common/EncoreBootImage.cpp
new file mode 100644 (file)
index 0000000..cca62b7
--- /dev/null
@@ -0,0 +1,1372 @@
+/*
+ * File:       EncoreBootImage.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "EncoreBootImage.h"
+#include <stdexcept>
+#include <algorithm>
+#include <time.h>
+#include "crc.h"
+#include "SHA1.h"
+#include "Random.h"
+#include "rijndael.h"
+#include "RijndaelCBCMAC.h"
+#include "Logging.h"
+#include "EndianUtilities.h"
+
+using namespace elftosb;
+
+EncoreBootImage::EncoreBootImage()
+:      m_headerFlags(0),
+       m_productVersion(),
+       m_componentVersion(),
+       m_driveTag(0)
+{
+}
+
+EncoreBootImage::~EncoreBootImage()
+{
+       // dispose of all sections
+       section_iterator_t it = beginSection();
+       for (; it != endSection(); ++it)
+       {
+               delete *it;
+       }
+}
+
+//! \exception std::runtime_error Raised if \a newSection has the same tag as a previously
+//!            added section.
+void EncoreBootImage::addSection(Section * newSection)
+{
+       // check for another section with this tag
+       section_iterator_t it = beginSection();
+       for (; it != endSection(); ++it)
+       {
+               if ((*it)->getIdentifier() == newSection->getIdentifier())
+               {
+                       throw std::runtime_error("new section with non-unique tag");
+               }
+       }
+       
+       // no conflicting section tags, so add it
+       m_sections.push_back(newSection);
+       
+       // tell the image who owns it now
+       newSection->setImage(this);
+}
+
+EncoreBootImage::section_iterator_t EncoreBootImage::findSection(Section * section)
+{
+       return std::find(beginSection(), endSection(), section);
+}
+
+void EncoreBootImage::setProductVersion(const version_t & version)
+{
+       m_productVersion = version;
+}
+
+void EncoreBootImage::setComponentVersion(const version_t & version)
+{
+       m_componentVersion = version;
+}
+
+//! \todo Optimize writing section data. Right now it only writes one block at a
+//!            time, which is of course quite slow (in relative terms).
+//!    \todo Refactor this into several different methods for writing each region
+//!            of the image. Use a context structure to keep track of shared data between
+//!            each of the methods.
+//! \todo Refactor the section and boot tag writing code to only have a single
+//!            copy of the block writing and encryption loop.
+void EncoreBootImage::writeToStream(std::ostream & stream)
+{
+       // always generate the session key or DEK even if image is unencrypted
+       m_sessionKey.randomize();
+       
+       // prepare to compute CBC-MACs with each KEK
+       unsigned i;
+       smart_array_ptr<RijndaelCBCMAC> macs(0);
+       if (isEncrypted())
+       {
+               macs = new RijndaelCBCMAC[m_keys.size()];
+               for (i=0; i < m_keys.size(); ++i)
+               {
+                       RijndaelCBCMAC mac(m_keys[i]);
+                       (macs.get())[i] = mac;
+               }
+       }
+       
+       // prepare to compute SHA-1 digest over entire image
+       CSHA1 hash;
+       hash.Reset();
+       
+       // count of total blocks written to the file
+       unsigned fileBlocksWritten = 0;
+
+       // we need some pieces of the header down below
+       boot_image_header_t imageHeader;
+       prepareImageHeader(imageHeader);
+       
+       // write plaintext header
+       {
+               // write header
+               assert(sizeOfPaddingForCipherBlocks(sizeof(boot_image_header_t)) == 0);
+               stream.write(reinterpret_cast<char *>(&imageHeader), sizeof(imageHeader));
+               fileBlocksWritten += numberOfCipherBlocks(sizeof(imageHeader));
+               
+               // update CBC-MAC over image header
+               if (isEncrypted())
+               {
+                       for (i=0; i < m_keys.size(); ++i)
+                       {
+                               (macs.get())[i].update(reinterpret_cast<uint8_t *>(&imageHeader), sizeof(imageHeader));
+                       }
+               }
+               
+               // update SHA-1
+               hash.Update(reinterpret_cast<uint8_t *>(&imageHeader), sizeof(imageHeader));
+       }
+       
+       // write plaintext section table
+       {
+               section_iterator_t it = beginSection();
+               for (; it != endSection(); ++it)
+               {
+                       Section * section = *it;
+                       
+                       // write header for this section
+                       assert(sizeOfPaddingForCipherBlocks(sizeof(section_header_t)) == 0);
+                       section_header_t sectionHeader;
+                       section->fillSectionHeader(sectionHeader);
+                       stream.write(reinterpret_cast<char *>(&sectionHeader), sizeof(sectionHeader));
+                       fileBlocksWritten += numberOfCipherBlocks(sizeof(sectionHeader));
+                       
+                       // update CBC-MAC over this entry
+                       if (isEncrypted())
+                       {
+                               for (i=0; i < m_keys.size(); ++i)
+                               {
+                                       (macs.get())[i].update(reinterpret_cast<uint8_t *>(&sectionHeader), sizeof(sectionHeader));
+                               }
+                       }
+                       
+                       // update SHA-1
+                       hash.Update(reinterpret_cast<uint8_t *>(&sectionHeader), sizeof(sectionHeader));
+               }
+       }
+       
+       // finished with the CBC-MAC
+       if (isEncrypted())
+       {
+               for (i=0; i < m_keys.size(); ++i)
+               {
+                       (macs.get())[i].finalize();
+               }
+       }
+       
+       // write key dictionary
+       if (isEncrypted())
+       {
+               key_iterator_t it = beginKeys();
+               for (i=0; it != endKeys(); ++it, ++i)
+               {
+                       // write CBC-MAC result for this key, then update SHA-1
+                       RijndaelCBCMAC & mac = (macs.get())[i];
+                       const RijndaelCBCMAC::block_t & macResult = mac.getMAC();
+                       stream.write(reinterpret_cast<const char *>(&macResult), sizeof(RijndaelCBCMAC::block_t));
+                       hash.Update(reinterpret_cast<const uint8_t *>(&macResult), sizeof(RijndaelCBCMAC::block_t));
+                       fileBlocksWritten++;
+                       
+                       // encrypt DEK with this key, write it out, and update image digest
+                       Rijndael cipher;
+                       cipher.init(Rijndael::CBC, Rijndael::Encrypt, *it, Rijndael::Key16Bytes, imageHeader.m_iv);
+                       AESKey<128>::key_t wrappedSessionKey;
+                       cipher.blockEncrypt(m_sessionKey, sizeof(AESKey<128>::key_t) * 8, wrappedSessionKey);
+                       stream.write(reinterpret_cast<char *>(&wrappedSessionKey), sizeof(wrappedSessionKey));
+                       hash.Update(reinterpret_cast<uint8_t *>(&wrappedSessionKey), sizeof(wrappedSessionKey));
+                       fileBlocksWritten++;
+               }
+       }
+       
+       // write sections and boot tags
+       {
+               section_iterator_t it = beginSection();
+               for (; it != endSection(); ++it)
+               {
+                       section_iterator_t itCopy = it;
+                       bool isLastSection = (++itCopy == endSection());
+                       
+                       Section * section = *it;
+                       cipher_block_t block;
+                       unsigned blockCount = section->getBlockCount();
+                       unsigned blocksWritten = 0;
+                       
+                       Rijndael cipher;
+                       cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, imageHeader.m_iv);
+                       
+                       // Compute the number of padding blocks needed to align the section. This first
+                       // call to getPadBlockCountForOffset() passes an offset that excludes
+                       // the boot tag for this section.
+                       unsigned paddingBlocks = getPadBlockCountForSection(section, fileBlocksWritten);
+                       
+                       // Insert nop commands as padding to align the start of the section, if
+                       // the section has special alignment requirements.
+                       NopCommand nop;
+                       while (paddingBlocks--)
+                       {
+                               blockCount = nop.getBlockCount();
+                               blocksWritten = 0;
+                               while (blocksWritten < blockCount)
+                               {
+                                       nop.getBlocks(blocksWritten, 1, &block);
+                                       
+                                       if (isEncrypted())
+                                       {
+                                               // re-init after encrypt to update IV
+                                               cipher.blockEncrypt(block, sizeof(cipher_block_t) * 8, block);
+                                               cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, block);
+                                       }
+                                       
+                                       stream.write(reinterpret_cast<char *>(&block), sizeof(cipher_block_t));
+                                       hash.Update(reinterpret_cast<uint8_t *>(&block), sizeof(cipher_block_t));
+                                       
+                                       blocksWritten++;
+                                       fileBlocksWritten++;
+                               }
+                       }
+                       
+                       // reinit cipher for boot tag
+                       cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, imageHeader.m_iv);
+                       
+                       // write boot tag
+                       TagCommand tag(*section);
+                       tag.setLast(isLastSection);
+                       if (!isLastSection)
+                       {
+                               // If this isn't the last section, the tag needs to include any
+                               // padding for the next section in its length, otherwise the ROM
+                               // won't be able to find the next section's boot tag.
+                               unsigned nextSectionOffset = fileBlocksWritten + section->getBlockCount() + 1;
+                               tag.setSectionLength(section->getBlockCount() + getPadBlockCountForSection(*itCopy, nextSectionOffset));
+                       }
+                       blockCount = tag.getBlockCount();
+                       blocksWritten = 0;
+                       while (blocksWritten < blockCount)
+                       {
+                               tag.getBlocks(blocksWritten, 1, &block);
+                               
+                               if (isEncrypted())
+                               {
+                                       // re-init after encrypt to update IV
+                                       cipher.blockEncrypt(block, sizeof(cipher_block_t) * 8, block);
+                                       cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, block);
+                               }
+                               
+                               stream.write(reinterpret_cast<char *>(&block), sizeof(cipher_block_t));
+                               hash.Update(reinterpret_cast<uint8_t *>(&block), sizeof(cipher_block_t));
+                               
+                               blocksWritten++;
+                               fileBlocksWritten++;
+                       }
+                       
+                       // reinit cipher for section data
+                       cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, imageHeader.m_iv);
+                       
+                       // write section data
+                       blockCount = section->getBlockCount();
+                       blocksWritten = 0;
+                       while (blocksWritten < blockCount)
+                       {
+                               section->getBlocks(blocksWritten, 1, &block);
+                               
+                               // Only encrypt the section contents if the entire boot image is encrypted
+                               // and the section doesn't have the "leave unencrypted" flag set. Even if the
+                               // section is unencrypted the boot tag will remain encrypted.
+                               if (isEncrypted() && !section->getLeaveUnencrypted())
+                               {
+                                       // re-init after encrypt to update IV
+                                       cipher.blockEncrypt(block, sizeof(cipher_block_t) * 8, block);
+                                       cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, block);
+                               }
+                               
+                               stream.write(reinterpret_cast<char *>(&block), sizeof(cipher_block_t));
+                               hash.Update(reinterpret_cast<uint8_t *>(&block), sizeof(cipher_block_t));
+                               
+                               blocksWritten++;
+                               fileBlocksWritten++;
+                       }
+               }
+       }
+       
+       // write SHA-1 digest over entire image
+       {
+               // allocate enough room for digest and bytes to pad out to the next cipher block
+               const unsigned padBytes = sizeOfPaddingForCipherBlocks(sizeof(sha1_digest_t));
+               unsigned digestBlocksSize = sizeof(sha1_digest_t) + padBytes;
+               smart_array_ptr<uint8_t> digestBlocks = new uint8_t[digestBlocksSize];
+               hash.Final();
+               hash.GetHash(digestBlocks.get());
+               
+               // set the pad bytes to random values
+               RandomNumberGenerator rng;
+               rng.generateBlock(&(digestBlocks.get())[sizeof(sha1_digest_t)], padBytes);
+               
+               // encrypt with session key
+               if (isEncrypted())
+               {
+                       Rijndael cipher;
+                       cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_sessionKey, Rijndael::Key16Bytes, imageHeader.m_iv);
+                       cipher.blockEncrypt(digestBlocks.get(), digestBlocksSize * 8, digestBlocks.get());
+               }
+               
+               // write to the stream
+               stream.write(reinterpret_cast<char *>(digestBlocks.get()), digestBlocksSize);
+       }
+}
+
+void EncoreBootImage::prepareImageHeader(boot_image_header_t & header)
+{
+       // get identifier for the first bootable section
+       Section * firstBootSection = findFirstBootableSection();
+       section_id_t firstBootSectionID = 0;
+       if (firstBootSection)
+       {
+               firstBootSectionID = firstBootSection->getIdentifier();
+       }
+       
+       // fill in header fields
+       header.m_signature[0] = 'S';
+       header.m_signature[1] = 'T';
+       header.m_signature[2] = 'M';
+       header.m_signature[3] = 'P';
+       header.m_majorVersion = ROM_BOOT_IMAGE_MAJOR_VERSION;
+       header.m_minorVersion = ROM_BOOT_IMAGE_MINOR_VERSION;
+       header.m_flags = ENDIAN_HOST_TO_LITTLE_U16(m_headerFlags);
+       header.m_imageBlocks = ENDIAN_HOST_TO_LITTLE_U32(getImageSize());
+       header.m_firstBootableSectionID = ENDIAN_HOST_TO_LITTLE_U32(firstBootSectionID);
+       header.m_keyCount = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)m_keys.size());
+       header.m_headerBlocks = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)numberOfCipherBlocks(sizeof(header)));
+       header.m_sectionCount = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)m_sections.size());
+       header.m_sectionHeaderSize = ENDIAN_HOST_TO_LITTLE_U16((uint16_t)numberOfCipherBlocks(sizeof(section_header_t)));
+       header.m_signature2[0] = 's';
+       header.m_signature2[1] = 'g';
+       header.m_signature2[2] = 't';
+       header.m_signature2[3] = 'l';
+       header.m_timestamp = ENDIAN_HOST_TO_LITTLE_U64(getTimestamp());
+       header.m_driveTag = m_driveTag;
+
+       // Prepare version fields by converting them to the correct byte order.
+       header.m_productVersion = m_productVersion;
+       header.m_componentVersion = m_componentVersion;
+       header.m_productVersion.fixByteOrder();
+       header.m_componentVersion.fixByteOrder();
+
+       // the fields are dependant on others
+       header.m_keyDictionaryBlock = ENDIAN_HOST_TO_LITTLE_U16(header.m_headerBlocks + header.m_sectionCount * header.m_sectionHeaderSize);
+       header.m_firstBootTagBlock = ENDIAN_HOST_TO_LITTLE_U32(header.m_keyDictionaryBlock + header.m_keyCount * 2);
+       
+       // generate random pad bytes
+       RandomNumberGenerator rng;
+       rng.generateBlock(header.m_padding0, sizeof(header.m_padding0));
+       rng.generateBlock(header.m_padding1, sizeof(header.m_padding1));
+       
+       // compute SHA-1 digest over the image header
+       uint8_t * message = reinterpret_cast<uint8_t *>(&header.m_signature);
+       uint32_t length = static_cast<uint32_t>(sizeof(header) - sizeof(header.m_digest)); // include padding
+       
+       CSHA1 hash;
+       hash.Reset();
+       hash.Update(message, length);
+       hash.Final();
+       hash.GetHash(header.m_digest);
+}
+
+//! Returns the number of microseconds since 00:00 1-1-2000. In actuality, the timestamp
+//! is only accurate to seconds, and is simply extended out to microseconds.
+//!
+//! \todo Use the operating system's low-level functions to get a true microsecond
+//!            timestamp, instead of faking it like we do now.
+//! \bug The timestamp might be off an hour.
+uint64_t EncoreBootImage::getTimestamp()
+{
+#if WIN32
+       struct tm epoch = { 0, 0, 0, 1, 0, 100, 0, 0 }; // 00:00 1-1-2000
+#else
+       struct tm epoch = { 0, 0, 0, 1, 0, 100, 0, 0, 1, 0, NULL }; // 00:00 1-1-2000
+#endif
+       time_t epochTime = mktime(&epoch);
+       time_t now = time(NULL);
+       now -= epochTime;
+       uint64_t microNow = uint64_t(now) * 1000000;    // convert to microseconds
+       return microNow;
+}
+
+//! Scans the section list looking for the first section which has
+//! the #ROM_SECTION_BOOTABLE flag set on it.
+EncoreBootImage::Section * EncoreBootImage::findFirstBootableSection()
+{
+       section_iterator_t it = beginSection();
+       for (; it != endSection(); ++it)
+       {
+               if ((*it)->getFlags() & ROM_SECTION_BOOTABLE)
+               {
+                       return *it;
+               }
+       }
+       
+       // no bootable sections were found
+       return NULL;
+}
+
+//! The boot tag for \a section is taken into account, thus making the
+//! result offset point to the first block of the actual section data.
+//!
+//! \note The offset will only be valid if all encryption keys and all
+//! sections have already been added to the image.
+uint32_t EncoreBootImage::getSectionOffset(Section * section)
+{
+       // start with boot image headers 
+       uint32_t offset = numberOfCipherBlocks(sizeof(boot_image_header_t));    // header
+       offset += numberOfCipherBlocks(sizeof(section_header_t)) * sectionCount();      // section table
+       offset += 2 * keyCount();       // key dictiontary
+       
+       // add up sections before this one
+       section_iterator_t it = beginSection();
+       for (; it != endSection() && *it != section; ++it)
+       {
+               Section * thisSection = *it;
+               
+               // insert padding for section alignment
+               offset += getPadBlockCountForSection(thisSection, offset);
+               
+               // add one for boot tag associated with this section
+               offset++;
+               
+               // now add the section's contents
+               offset += thisSection->getBlockCount();
+       }
+       
+       // and add padding for this section
+       offset += getPadBlockCountForSection(section, offset);
+       
+       // skip over this section's boot tag
+       offset++;
+       
+       return offset;
+}
+
+//! Computes the number of blocks of padding required to align \a section while
+//! taking into account the boot tag that gets inserted before the section contents.
+unsigned EncoreBootImage::getPadBlockCountForSection(Section * section, unsigned offset)
+{
+       // Compute the number of padding blocks needed to align the section. This first
+       // call to getPadBlockCountForOffset() passes an offset that excludes
+       // the boot tag for this section.
+       unsigned paddingBlocks = section->getPadBlockCountForOffset(offset);
+       
+       // If the pad count comes back as 0 then we need to try again with an offset that
+       // includes the boot tag. This is all because we're aligning the section contents
+       // start and not the section's boot tag.
+       if (paddingBlocks == 0)
+       {
+               paddingBlocks = section->getPadBlockCountForOffset(offset + 1);
+       }
+       // Otherwise if we get a nonzero pad amount then we need to subtract the block
+       // for the section's boot tag from the pad count.
+       else
+       {
+               paddingBlocks--;
+       }
+       
+       return paddingBlocks;
+}
+
+uint32_t EncoreBootImage::getImageSize()
+{
+       // determine to total size of the image
+       const uint32_t headerBlocks = numberOfCipherBlocks(sizeof(boot_image_header_t));
+       const uint32_t sectionHeaderSize = numberOfCipherBlocks(sizeof(section_header_t));
+       uint32_t imageBlocks = headerBlocks;
+       imageBlocks += sectionHeaderSize * m_sections.size();   // section table
+       imageBlocks += 2 * m_keys.size();       // key dict
+       
+       // add in each section's size
+       section_iterator_t it = beginSection();
+       for (; it != endSection(); ++it)
+       {
+               // add in this section's size, padding to align it, and its boot tag
+               imageBlocks += getPadBlockCountForSection(*it, imageBlocks);
+               imageBlocks += (*it)->getBlockCount();
+               imageBlocks++;
+       }
+       
+       // image MAC
+       imageBlocks += 2;
+       
+       return imageBlocks;
+}
+
+void EncoreBootImage::debugPrint() const
+{
+       const_section_iterator_t it = beginSection();
+       for (; it != endSection(); ++it)
+       {
+               const Section * section = *it;
+               section->debugPrint();
+       }
+}
+
+//! \param blocks Pointer to the raw data blocks.
+//! \param count Number of blocks pointed to by \a blocks.
+//! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied
+//!            by the command. Should be at least 1 for every command. This must not be NULL
+//!            on entry!
+//!
+//! \return A new boot command instance.
+//! \retval NULL The boot command pointed to by \a blocks was not recognized as a known
+//!     command type.
+//!
+//! \exception std::runtime_error This exception indicates that a command was recognized
+//!     but contained invalid data. Compare this to a NULL result which indicates that
+//!     no command was recognized at all.
+EncoreBootImage::BootCommand * EncoreBootImage::BootCommand::createFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)
+{
+       const boot_command_t * header = reinterpret_cast<const boot_command_t *>(blocks);
+    BootCommand * command = NULL;
+       
+    switch (header->m_tag)
+    {
+        case ROM_NOP_CMD:
+            command = new NopCommand();
+            break;
+        case ROM_TAG_CMD:
+            command = new TagCommand();
+            break;
+        case ROM_LOAD_CMD:
+            command = new LoadCommand();
+            break;
+        case ROM_FILL_CMD:
+            command = new FillCommand();
+            break;
+        case ROM_MODE_CMD:
+            command = new ModeCommand();
+            break;
+        case ROM_JUMP_CMD:
+            command = new JumpCommand();
+            break;
+        case ROM_CALL_CMD:
+            command = new CallCommand();
+            break;
+    }
+    
+    if (command)
+    {
+        command->initFromData(blocks, count, consumed);
+    }
+    return command;
+}
+
+//! The checksum algorithm is totally straightforward, except that the
+//! initial checksum byte value is set to 0x5a instead of 0.
+uint8_t EncoreBootImage::BootCommand::calculateChecksum(const boot_command_t & header)
+{
+       const uint8_t * bytes = reinterpret_cast<const uint8_t *>(&header);
+       uint8_t checksum = 0x5a;
+       int i;
+       
+       // start at one to skip checksum field
+       for (i = 1; i < sizeof(header); ++i)
+       {
+               checksum += bytes[i];
+       }
+       
+       return checksum;
+}
+
+//! The default implementation returns 0, indicating that no blocks are
+//! available.
+unsigned EncoreBootImage::BootCommand::getBlockCount() const
+{
+       return 1 + getDataBlockCount();
+}
+
+//! Up to \a maxCount cipher blocks are copied into the buffer pointed to by
+//! the \a data argument. The index of the first block to copy is
+//! held in the \a offset argument.
+//!
+//! \param offset Starting block number to copy. Zero means the first available block.
+//! \param maxCount Up to this number of blocks may be copied into \a data. Must be 1 or greater.
+//! \param data Buffer for outgoing cipher blocks. Must have enough room to hold
+//!            \a maxCount blocks.
+//!
+//! \return The number of cipher blocks copied into \a data.
+//! \retval 0 No more blocks are available and nothing was written to \a data.
+//!
+//! \exception std::out_of_range If \a offset is invalid.
+unsigned EncoreBootImage::BootCommand::getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data)
+{
+       assert(data);
+       assert(maxCount >= 1);
+       
+       // check for valid offset
+       if (offset >= getBlockCount())
+       {
+               throw std::out_of_range("invalid offset");
+       }
+       
+       // handle the command header block separately
+       if (offset == 0)
+       {
+               assert(sizeof(boot_command_t) == sizeof(cipher_block_t));
+               
+               boot_command_t header;
+               fillCommandHeader(header);
+               memcpy(data, &header, sizeof(header));
+               
+               return 1;
+       }
+       
+       // handle any data blocks
+       return getDataBlocks(offset - 1, maxCount, data);
+}
+
+//! The checksum field of \a testHeader is always computed and checked against itself.
+//! All other fields are compared to the corresponding value set in \a modelHeader
+//! if the appropriate flag is set in \a whichFields. For example, the m_address fields
+//! in \a testHeader and \a modelHeader are compared when the CMD_ADDRESS_FIELD bit
+//! is set in \a whichFields. An exception is thrown if any comparison fails.
+//!
+//! \param modelHeader The baseline header to compare against. Only those fields that
+//!            have corresponding bits set in \a whichFields need to be set.
+//! \param testHeader The actual command header which is being validated.
+//! \param whichFields A bitfield used to determine which fields of the boot command
+//!            header are compared. Possible values are:
+//!                    - CMD_TAG_FIELD
+//!                    - CMD_FLAGS_FIELD
+//!                    - CMD_ADDRESS_FIELD
+//!                    - CMD_COUNT_FIELD
+//!                    - CMD_DATA_FIELD
+//!
+//! \exception std::runtime_error Thrown if any requested validation fails.
+void EncoreBootImage::BootCommand::validateHeader(const boot_command_t * modelHeader, const boot_command_t * testHeader, unsigned whichFields)
+{
+       // compare all the fields that were requested
+       if ((whichFields & CMD_TAG_FIELD) && (testHeader->m_tag != modelHeader->m_tag))
+       {
+               throw std::runtime_error("invalid tag field");
+       }
+       
+       if ((whichFields & CMD_FLAGS_FIELD) && (testHeader->m_flags != modelHeader->m_flags))
+       {
+               throw std::runtime_error("invalid flags field");
+       }
+       
+       if ((whichFields & CMD_ADDRESS_FIELD) && (testHeader->m_address != modelHeader->m_address))
+       {
+               throw std::runtime_error("invalid address field");
+       }
+       
+       if ((whichFields & CMD_COUNT_FIELD) && (testHeader->m_count != modelHeader->m_count))
+       {
+               throw std::runtime_error("invalid count field");
+       }
+       
+       if ((whichFields & CMD_DATA_FIELD) && (testHeader->m_data != modelHeader->m_data))
+       {
+               throw std::runtime_error("invalid data field");
+       }
+       
+       // calculate checksum
+       uint8_t testChecksum = calculateChecksum(*testHeader);
+       if (testChecksum != testHeader->m_checksum)
+       {
+               throw std::runtime_error("invalid checksum");
+       }
+}
+
+//! Since the NOP command has no data, this method just validates the command header.
+//! All fields except the checksum are expected to be set to 0.
+//!
+//! \param blocks Pointer to the raw data blocks.
+//! \param count Number of blocks pointed to by \a blocks.
+//! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied
+//!            by the command. Should be at least 1 for every command. This must not be NULL
+//!            on entry!
+//!
+//! \exception std::runtime_error Thrown if header fields are invalid.
+void EncoreBootImage::NopCommand::initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)
+{
+       const boot_command_t model = { 0, ROM_NOP_CMD, 0, 0, 0, 0 };
+       const boot_command_t * header = reinterpret_cast<const boot_command_t *>(blocks);
+       validateHeader(&model, header, CMD_TAG_FIELD | CMD_FLAGS_FIELD | CMD_ADDRESS_FIELD | CMD_COUNT_FIELD | CMD_DATA_FIELD);
+       
+       *consumed = 1;
+}
+
+//! All fields of the boot command header structure are set to 0, except
+//! for the checksum. This includes the tag field since the tag value for
+//! the #ROM_NOP_CMD is zero. And since all fields are zeroes the checksum
+//! remains the initial checksum value of 0x5a.
+void EncoreBootImage::NopCommand::fillCommandHeader(boot_command_t & header)
+{
+       header.m_tag = getTag();
+       header.m_flags = 0;
+       header.m_address = 0;
+       header.m_count = 0;
+       header.m_data = 0;
+       header.m_checksum = calculateChecksum(header);  // do this last
+}
+
+void EncoreBootImage::NopCommand::debugPrint() const
+{
+       Log::log(Logger::INFO2, "\tNOOP\n");
+}
+
+//! The identifier, length, and flags fields are taken from \a section.
+//!
+//! \todo How does length get set correctly if the length is supposed to include
+//!            this command?
+EncoreBootImage::TagCommand::TagCommand(const Section & section)
+{
+       m_sectionIdentifier = section.getIdentifier();
+       m_sectionLength = section.getBlockCount();
+       m_sectionFlags = section.getFlags();
+}
+
+//! \param blocks Pointer to the raw data blocks.
+//! \param count Number of blocks pointed to by \a blocks.
+//! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied
+//!            by the command. Should be at least 1 for every command. This must not be NULL
+//!            on entry!
+//!
+//! \exception std::runtime_error Thrown if header fields are invalid.
+void EncoreBootImage::TagCommand::initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)
+{
+       const boot_command_t model = { 0, ROM_TAG_CMD, 0, 0, 0, 0 };
+       const boot_command_t * header = reinterpret_cast<const boot_command_t *>(blocks);
+       validateHeader(&model, header, CMD_TAG_FIELD);
+       
+    // read fields from header
+       m_isLast = (ENDIAN_LITTLE_TO_HOST_U16(header->m_flags) & ROM_LAST_TAG) != 0;
+       m_sectionIdentifier = ENDIAN_LITTLE_TO_HOST_U32(header->m_address);
+       m_sectionLength = ENDIAN_LITTLE_TO_HOST_U32(header->m_count);
+       m_sectionFlags = ENDIAN_LITTLE_TO_HOST_U32(header->m_data);
+       
+       *consumed = 1;
+}
+
+//! This method currently assumes that the next tag command will come immediately
+//! after the data for this section.
+void EncoreBootImage::TagCommand::fillCommandHeader(boot_command_t & header)
+{
+       header.m_tag = getTag();
+       header.m_flags = ENDIAN_HOST_TO_LITTLE_U16(m_isLast ? ROM_LAST_TAG : 0);
+       header.m_address = ENDIAN_HOST_TO_LITTLE_U32(m_sectionIdentifier);
+       header.m_count = ENDIAN_HOST_TO_LITTLE_U32(m_sectionLength);
+       header.m_data = ENDIAN_HOST_TO_LITTLE_U32(m_sectionFlags);
+       header.m_checksum = calculateChecksum(header);  // do this last
+}
+
+void EncoreBootImage::TagCommand::debugPrint() const
+{
+       Log::log(Logger::INFO2, "  BTAG | sec=0x%08x | cnt=0x%08x | flg=0x%08x\n", m_sectionIdentifier, m_sectionLength, m_sectionFlags);
+}
+
+//! All fields are set to zero.
+//!
+EncoreBootImage::LoadCommand::LoadCommand()
+:      BootCommand(), m_data(), m_padCount(0), m_length(0), m_address(0), m_loadDCD(false)
+{
+       fillPadding();
+}
+
+EncoreBootImage::LoadCommand::LoadCommand(uint32_t address, const uint8_t * data, uint32_t length)
+:      BootCommand(), m_data(), m_padCount(0), m_length(0), m_address(address), m_loadDCD(false)
+{
+       fillPadding();
+       setData(data, length);
+}
+
+//! \param blocks Pointer to the raw data blocks.
+//! \param count Number of blocks pointed to by \a blocks.
+//! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied
+//!            by the command. Should be at least 1 for every command. This must not be NULL
+//!            on entry!
+//!
+//! \exception std::runtime_error This exception is thrown if the actual CRC of the load
+//!     data does not match the CRC stored in the command header. Also thrown if the
+//!     \a count parameter is less than the number of data blocks needed for the length
+//!     specified in the command header or if header fields are invalid.
+void EncoreBootImage::LoadCommand::initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)
+{
+    // check static fields
+       const boot_command_t model = { 0, ROM_LOAD_CMD, 0, 0, 0, 0 };
+       const boot_command_t * header = reinterpret_cast<const boot_command_t *>(blocks);
+       validateHeader(&model, header, CMD_TAG_FIELD);
+       
+    // read fields from header
+       m_address = ENDIAN_LITTLE_TO_HOST_U32(header->m_address);
+       m_length = ENDIAN_LITTLE_TO_HOST_U32(header->m_count);
+    unsigned crc = ENDIAN_LITTLE_TO_HOST_U32(header->m_data);
+    unsigned dataBlockCount = numberOfCipherBlocks(m_length);
+    m_padCount = sizeOfPaddingForCipherBlocks(dataBlockCount);
+       m_loadDCD = (ENDIAN_LITTLE_TO_HOST_U16(header->m_flags) & ROM_LOAD_DCD) != 0;
+       
+    // make sure there are enough blocks
+    if (count - 1 < dataBlockCount)
+    {
+        throw std::runtime_error("not enough cipher blocks for load data");
+    }
+    
+    // copy data
+    setData(reinterpret_cast<const uint8_t *>(blocks + 1), m_length);
+    
+    // copy padding
+    if (m_padCount)
+    {
+        const uint8_t * firstPadByte = reinterpret_cast<const uint8_t *> (blocks + (1 + dataBlockCount)) - m_padCount;
+        memcpy(m_padding, firstPadByte, m_padCount);
+    }
+    
+    // check CRC
+    uint32_t actualCRC = calculateCRC();
+    if (actualCRC != crc)
+    {
+        throw std::runtime_error("load data failed CRC check");
+    }
+    
+       *consumed = 1 + dataBlockCount;
+}
+
+//! The only thing unique in the load command header is the
+//! #elftosb::EncoreBootImage::boot_command_t::m_data. It contains a CRC-32 over the
+//! load data, plus any bytes of padding in the last data cipher block.
+void EncoreBootImage::LoadCommand::fillCommandHeader(boot_command_t & header)
+{
+       header.m_tag = getTag();
+       header.m_flags = ENDIAN_HOST_TO_LITTLE_U16(m_loadDCD ? ROM_LOAD_DCD : 0);
+       header.m_address = ENDIAN_HOST_TO_LITTLE_U32(m_address);
+       header.m_count = ENDIAN_HOST_TO_LITTLE_U32(m_length);
+       header.m_data = ENDIAN_HOST_TO_LITTLE_U32(calculateCRC());
+       
+       // do this last
+       header.m_checksum = calculateChecksum(header);
+}
+
+//! A CRC-32 is calculated over the load data, including any pad bytes
+//! that are required in the last data cipher block. Including the
+//! pad bytes in the CRC makes it vastly easier for the ROM to calculate
+//! the CRC for validation.
+uint32_t EncoreBootImage::LoadCommand::calculateCRC() const
+{
+       uint32_t result;
+       CRC32 crc;
+       crc.update(m_data, m_length);
+       if (m_padCount)
+       {
+               // include random padding in the CRC
+               crc.update(m_padding, m_padCount);
+       }
+       crc.truncatedFinal(reinterpret_cast<uint8_t*>(&result), sizeof(result));
+       
+       return result;
+}
+
+//! A local copy of the load data is made. This copy will be disposed of when this object
+//! is destroyed. This means the caller is free to deallocate \a data after this call
+//! returns. It also means the caller can pass a pointer into the middle of a buffer for
+//! \a data and not worry about ownership issues. 
+void EncoreBootImage::LoadCommand::setData(const uint8_t * data, uint32_t length)
+{
+       assert(data);
+       assert(length);
+       
+       uint8_t * dataCopy = new uint8_t[length];
+       memcpy(dataCopy, data, length);
+       
+       m_data = dataCopy;
+       m_length = length;
+       
+       m_padCount = sizeOfPaddingForCipherBlocks(m_length);
+}
+
+//! \return The number of cipher blocks required to hold the load data,
+//!            rounded up as necessary.
+unsigned EncoreBootImage::LoadCommand::getDataBlockCount() const
+{
+       // round up to the next cipher block
+       return numberOfCipherBlocks(m_length);
+}
+
+//! Up to \a maxCount data blocks are copied into the buffer pointed to by
+//! the \a data argument. This is only a request for \a maxCount blocks.
+//! A return value of 0 indicates that no more blocks are available. The
+//! index of the first block to copy is held in the \a offset argument.
+//! If there are pad bytes needed to fill out the last data block, they
+//! will be filled with random data in order to add to the "whiteness" of
+//! the data on both sides of encryption.
+//!
+//! \param offset Starting block number to copy. Zero means the first available block.
+//! \param maxCount Up to this number of blocks may be copied into \a data. Must be 1 or greater.
+//! \param data Buffer for outgoing data blocks. Must have enough room to hold
+//!            \a maxCount blocks.
+//!
+//! \return The number of data blocks copied into \a data.
+//! \retval 0 No more blocks are available and nothing was written to \a data.
+//!
+//! \exception std::out_of_range Thrown when offset is invalid.
+//!
+//! \todo fill pad bytes with random bytes
+unsigned EncoreBootImage::LoadCommand::getDataBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data)
+{
+       assert(data);
+       assert(maxCount != 0);
+       
+       uint32_t blockCount = getDataBlockCount();
+       
+       // check offset
+       if (offset >= blockCount)
+       {
+               throw std::out_of_range("invalid offset");
+       }
+       
+       // figure out how many blocks to return
+       unsigned resultBlocks = blockCount - offset;
+       if (resultBlocks > maxCount)
+       {
+               resultBlocks = maxCount;
+               
+               // exclude last block if there is padding
+               if (m_padCount && (offset != blockCount - 1) && (offset + resultBlocks == blockCount))
+               {
+                       resultBlocks--;
+               }
+       }
+       
+       // if there are pad bytes, handle the last block specially
+       if (m_padCount && offset == blockCount - 1)
+       {
+               // copy the remainder of the load data into the first part of the result block
+               unsigned remainderLength = sizeof(cipher_block_t) - m_padCount;
+               memcpy(data, &m_data[sizeof(cipher_block_t) * offset], remainderLength);
+               
+               // copy pad bytes we previously generated into the last part of the result block
+               // data is a cipher block pointer, so indexing is done on cipher block
+               // boundaries, thus we need a byte pointer to index properly
+               uint8_t * bytePtr = reinterpret_cast<uint8_t*>(data);
+               memcpy(bytePtr + remainderLength, &m_padding, m_padCount);
+       }
+       else
+       {
+               memcpy(data, &m_data[sizeof(cipher_block_t) * offset], sizeof(cipher_block_t) * resultBlocks);
+       }
+       
+       return resultBlocks;
+}
+
+//! Fills #m_padding with random bytes that may be used to fill up the last data
+//! cipher block.
+void EncoreBootImage::LoadCommand::fillPadding()
+{
+       RandomNumberGenerator rng;
+       rng.generateBlock(m_padding, sizeof(m_padding));
+}
+
+void EncoreBootImage::LoadCommand::debugPrint() const
+{
+       Log::log(Logger::INFO2, "  LOAD | adr=0x%08x | len=0x%08x | crc=0x%08x | flg=0x%08x\n", m_address, m_length, calculateCRC(), m_loadDCD ? ROM_LOAD_DCD : 0);
+}
+
+//! The pattern, address, and count are all initialized to zero, and the pattern
+//! size is set to a word.
+EncoreBootImage::FillCommand::FillCommand()
+:      BootCommand(), m_address(0), m_count(0), m_pattern(0)
+{
+}
+
+//! \param blocks Pointer to the raw data blocks.
+//! \param count Number of blocks pointed to by \a blocks.
+//! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied
+//!            by the command. Should be at least 1 for every command. This must not be NULL
+//!            on entry!
+//!
+//! \exception std::runtime_error Thrown if header fields are invalid.
+void EncoreBootImage::FillCommand::initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)
+{
+    // check static fields
+       const boot_command_t model = { 0, ROM_FILL_CMD, 0, 0, 0, 0 };
+       const boot_command_t * header = reinterpret_cast<const boot_command_t *>(blocks);
+       validateHeader(&model, header, CMD_TAG_FIELD | CMD_FLAGS_FIELD);
+       
+    // read fields from header
+       m_address = ENDIAN_LITTLE_TO_HOST_U32(header->m_address);
+       m_count = ENDIAN_LITTLE_TO_HOST_U32(header->m_count);
+    m_pattern = ENDIAN_LITTLE_TO_HOST_U32(header->m_data);
+    
+       *consumed = 1;
+}
+
+void EncoreBootImage::FillCommand::fillCommandHeader(boot_command_t & header)
+{
+       header.m_tag = getTag();
+       header.m_flags = 0;
+       header.m_address = ENDIAN_HOST_TO_LITTLE_U32(m_address);
+       header.m_count = ENDIAN_HOST_TO_LITTLE_U32(m_count);
+       header.m_data = ENDIAN_HOST_TO_LITTLE_U32(m_pattern);
+       header.m_checksum = calculateChecksum(header);  // do this last
+}
+
+//! Extends the pattern across 32 bits.
+//!
+void EncoreBootImage::FillCommand::setPattern(uint8_t pattern)
+{
+       m_pattern = (pattern << 24) | (pattern << 16) | (pattern << 8) | pattern;
+}
+
+//! Extends the pattern across 32 bits.
+//!
+void EncoreBootImage::FillCommand::setPattern(uint16_t pattern)
+{
+       m_pattern = (pattern << 16) | pattern;
+}
+
+void EncoreBootImage::FillCommand::setPattern(uint32_t pattern)
+{
+       m_pattern = pattern;
+}
+
+void EncoreBootImage::FillCommand::debugPrint() const
+{
+       Log::log(Logger::INFO2, "  FILL | adr=0x%08x | len=0x%08x | ptn=0x%08x\n", m_address, m_count, m_pattern);
+}
+
+//! \param blocks Pointer to the raw data blocks.
+//! \param count Number of blocks pointed to by \a blocks.
+//! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied
+//!            by the command. Should be at least 1 for every command. This must not be NULL
+//!            on entry!
+//!
+//! \exception std::runtime_error Thrown if header fields are invalid.
+void EncoreBootImage::ModeCommand::initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)
+{
+    // check static fields
+       const boot_command_t model = { 0, ROM_MODE_CMD, 0, 0, 0, 0 };
+       const boot_command_t * header = reinterpret_cast<const boot_command_t *>(blocks);
+       validateHeader(&model, header, CMD_TAG_FIELD | CMD_FLAGS_FIELD | CMD_ADDRESS_FIELD | CMD_COUNT_FIELD);
+       
+    // read fields from header
+    m_mode = ENDIAN_LITTLE_TO_HOST_U32(header->m_data);
+    
+       *consumed = 1;
+}
+
+void EncoreBootImage::ModeCommand::fillCommandHeader(boot_command_t & header)
+{
+       header.m_tag = getTag();
+       header.m_flags = 0;
+       header.m_address = 0;
+       header.m_count = 0;
+       header.m_data = ENDIAN_HOST_TO_LITTLE_U32(m_mode);
+       header.m_checksum = calculateChecksum(header);  // do this last
+}
+
+void EncoreBootImage::ModeCommand::debugPrint() const
+{
+       Log::log(Logger::INFO2, "  MODE | mod=0x%08x\n", m_mode);
+}
+
+//! \param blocks Pointer to the raw data blocks.
+//! \param count Number of blocks pointed to by \a blocks.
+//! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied
+//!            by the command. Should be at least 1 for every command. This must not be NULL
+//!            on entry!
+//!
+//! \exception std::runtime_error Thrown if header fields are invalid.
+void EncoreBootImage::JumpCommand::initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)
+{
+    // check static fields
+       const boot_command_t model = { 0, getTag(), 0, 0, 0, 0 };
+       const boot_command_t * header = reinterpret_cast<const boot_command_t *>(blocks);
+       validateHeader(&model, header, CMD_TAG_FIELD | CMD_COUNT_FIELD);
+       
+    // read fields from header
+    m_address = ENDIAN_LITTLE_TO_HOST_U32(header->m_address);
+    m_argument = ENDIAN_LITTLE_TO_HOST_U32(header->m_data);
+       m_isHAB = (ENDIAN_LITTLE_TO_HOST_U16(header->m_flags) & ROM_HAB_EXEC) != 0;
+    
+       *consumed = 1;
+}
+
+void EncoreBootImage::JumpCommand::fillCommandHeader(boot_command_t & header)
+{
+       header.m_tag = getTag();
+       header.m_flags = ENDIAN_HOST_TO_LITTLE_U16(m_isHAB ? ROM_HAB_EXEC : 0);
+       header.m_address = ENDIAN_HOST_TO_LITTLE_U32(m_address);
+       header.m_count = 0;
+       header.m_data = ENDIAN_HOST_TO_LITTLE_U32(m_argument);
+       header.m_checksum = calculateChecksum(header);  // do this last
+}
+
+void EncoreBootImage::JumpCommand::debugPrint() const
+{
+       Log::log(Logger::INFO2, "  JUMP | adr=0x%08x | arg=0x%08x | flg=0x%08x\n", m_address, m_argument, m_isHAB ? ROM_HAB_EXEC : 0);
+}
+
+void EncoreBootImage::CallCommand::debugPrint() const
+{
+       Log::log(Logger::INFO2, "  CALL | adr=0x%08x | arg=0x%08x | flg=0x%08x\n", m_address, m_argument, m_isHAB ? ROM_HAB_EXEC : 0);
+}
+
+//! Only if the section has been assigned a boot image owner object will this
+//! method be able to fill in the #section_header_t::m_offset field. If no
+//! boot image has been set the offset will be set to 0.
+void EncoreBootImage::Section::fillSectionHeader(section_header_t & header)
+{
+       header.m_tag = getIdentifier();
+       header.m_offset = 0;
+       header.m_length = ENDIAN_HOST_TO_LITTLE_U32(getBlockCount());
+       header.m_flags = ENDIAN_HOST_TO_LITTLE_U32(getFlags());
+       
+       // if we're attached to an image, we can compute our real offset
+       if (m_image)
+       {
+               header.m_offset = ENDIAN_HOST_TO_LITTLE_U32(m_image->getSectionOffset(this));
+       }
+}
+
+//! The alignment will never be less than 16, since that is the size of the
+//! cipher block which is the basic unit of the boot image format. If an
+//! alignment less than 16 is set it will be ignored.
+//!
+//! \param alignment Alignment in bytes for this section. Must be a power of two.
+//!            Ignored if less than 16.
+void EncoreBootImage::Section::setAlignment(unsigned alignment)
+{
+       if (alignment > BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT)
+       {
+               m_alignment = alignment;
+       }
+}
+
+//! This method calculates the number of padding blocks that need to be inserted
+//! from a given offset for the section to be properly aligned. The value returned
+//! is the number of padding blocks that should be inserted starting just after
+//! \a offset to align the first cipher block of the section contents. The section's
+//! boot tag is \i not taken into account by this method, so the caller must
+//! deal with that herself.
+//!
+//! \param offset Start offset in cipher blocks (not bytes).
+//!
+//! \return A number of cipher blocks of padding to insert.
+unsigned EncoreBootImage::Section::getPadBlockCountForOffset(unsigned offset)
+{
+       // convert alignment from byte to block alignment
+       unsigned blockAlignment = m_alignment >> 4;
+       
+       unsigned nextAlignmentOffset = (offset + blockAlignment - 1) / blockAlignment * blockAlignment;
+       
+       return nextAlignmentOffset - offset;
+}
+
+EncoreBootImage::BootSection::~BootSection()
+{
+       deleteCommands();
+}
+
+void EncoreBootImage::BootSection::deleteCommands()
+{
+       // dispose of all sections
+       iterator_t it = begin();
+       for (; it != end(); ++it)
+       {
+               delete *it;
+       }
+}
+
+//! Always returns at least 1 for the required tag command.
+//!
+unsigned EncoreBootImage::BootSection::getBlockCount() const
+{
+       unsigned count = 0;
+       
+       const_iterator_t it = begin();
+       for (; it != end(); ++it)
+       {
+               count += (*it)->getBlockCount();
+       }
+       
+       return count;
+}
+
+//! Up to \a maxCount cipher blocks are copied into the buffer pointed to by
+//! the \a data argument. A return value of 0 indicates that
+//! no more blocks are available. The index of the first block to copy is
+//! held in the \a offset argument.
+//!
+//! \param offset Starting block number to copy. Zero means the first available block.
+//! \param maxCount Up to this number of blocks may be copied into \a data.
+//! \param data Buffer for outgoing cipher blocks. Must have enough room to hold
+//!            \a maxCount blocks.
+//!
+//! \return The number of cipher blocks copied into \a data.
+//! \retval 0 No more blocks are available and nothing was written to \a data.
+unsigned EncoreBootImage::BootSection::getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data)
+{
+       assert(data);
+       assert(maxCount >= 1);
+       
+       unsigned currentOffset = 0;
+       unsigned readCount = maxCount;
+       
+       iterator_t it = begin();
+       for (; it != end(); ++it)
+       {
+               BootCommand * command = *it;
+               unsigned commandBlocks = command->getBlockCount();
+               
+               // this should never be false!
+               assert(offset >= currentOffset);
+               
+               // skip forward until we hit the requested offset
+               if (offset >= currentOffset + commandBlocks)
+               {
+                       currentOffset += commandBlocks;
+                       continue;
+               }
+               
+               // read from this command
+               unsigned commandOffset = offset - currentOffset;
+               unsigned commandRemaining = commandBlocks - commandOffset;
+               if (readCount > commandRemaining)
+               {
+                       readCount = commandRemaining;
+               }
+               return command->getBlocks(commandOffset, readCount, data);
+       }
+       
+       return 0;
+}
+
+//! The entire contents of the section must be in memory, pointed to by \a blocks.
+//! Any commands that had previously been added to the section are disposed of.
+//!
+//! \param blocks Pointer to the section contents.
+//! \param count Number of blocks pointed to by \a blocks.
+//!
+//! \exception std::runtime_error Thrown if a boot command cannot be created from
+//!            the cipher block stream.
+void EncoreBootImage::BootSection::fillFromData(const cipher_block_t * blocks, unsigned count)
+{
+       // start with an empty slate
+       deleteCommands();
+       
+       const cipher_block_t * currentBlock = blocks;
+       unsigned remaining = count;
+       while (remaining)
+       {
+               // try to create a command from the next cipher block. the number of
+               // blocks the command used up is returned in consumed.
+               unsigned consumed;
+               BootCommand * command = BootCommand::createFromData(currentBlock, remaining, &consumed);
+               if (!command)
+               {
+                       throw std::runtime_error("invalid boot section data");
+               }
+               
+               addCommand(command);
+               
+               // update loop counters
+               remaining -= consumed;
+               currentBlock += consumed;
+       }
+}
+
+void EncoreBootImage::BootSection::debugPrint() const
+{
+       Log::log(Logger::INFO2, "Boot Section 0x%08x:\n", m_identifier);
+       
+       const_iterator_t it = begin();
+       for (; it != end(); ++it)
+       {
+               const BootCommand * command = *it;
+               command->debugPrint();
+       }
+}
+
+//! A copy is made of \a data. Any previously assigned data is disposed of.
+//!
+void EncoreBootImage::DataSection::setData(const uint8_t * data, unsigned length)
+{
+       m_data = new uint8_t[length];
+       memcpy(m_data.get(), data, length);
+       m_length = length;
+}
+
+//! The section takes ownership of \a data and will dispose of it using the
+//! array delete operator upon its destruction.
+void EncoreBootImage::DataSection::setDataNoCopy(const uint8_t * data, unsigned length)
+{
+       m_data = data;
+       m_length = length;
+}
+
+unsigned EncoreBootImage::DataSection::getBlockCount() const
+{
+       return numberOfCipherBlocks(m_length);
+}
+
+unsigned EncoreBootImage::DataSection::getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data)
+{
+       assert(data);
+       assert(maxCount != 0);
+       
+       unsigned blockCount = getBlockCount();
+       unsigned padCount = sizeOfPaddingForCipherBlocks(m_length);
+       
+       // check offset
+       if (offset >= blockCount)
+       {
+               throw std::out_of_range("invalid offset");
+       }
+       
+       // figure out how many blocks to return
+       unsigned resultBlocks = blockCount - offset;
+       if (resultBlocks > maxCount)
+       {
+               resultBlocks = maxCount;
+               
+               // exclude last block if there is padding
+               if (padCount && (offset != blockCount - 1) && (offset + resultBlocks == blockCount))
+               {
+                       resultBlocks--;
+               }
+       }
+       
+       // if there are pad bytes, handle the last block specially
+       if (padCount && offset == blockCount - 1)
+       {
+               // copy the remainder of the load data into the first part of the result block
+               unsigned remainderLength = sizeof(cipher_block_t) - padCount;
+               memcpy(data, &m_data[sizeOfCipherBlocks(offset)], remainderLength);
+               
+               // set pad bytes to zeroes.
+               // data is a cipher block pointer, so indexing is done on cipher block
+               // boundaries, thus we need a byte pointer to index properly
+               uint8_t * bytePtr = reinterpret_cast<uint8_t*>(data);
+               memset(bytePtr + remainderLength, 0, padCount);
+       }
+       else
+       {
+               memcpy(data, &m_data[sizeOfCipherBlocks(offset)], sizeOfCipherBlocks(resultBlocks));
+       }
+       
+       return resultBlocks;
+}
+
+void EncoreBootImage::DataSection::debugPrint() const
+{
+       Log::log(Logger::INFO2, "Data Section 0x%08x: (%d bytes, %d blocks)\n", m_identifier, m_length, getBlockCount());
+}
+
diff --git a/tools/elftosb/common/EncoreBootImage.h b/tools/elftosb/common/EncoreBootImage.h
new file mode 100644 (file)
index 0000000..1e78aee
--- /dev/null
@@ -0,0 +1,967 @@
+/*
+ * File:       EncoreBootImage.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_EncoreBootImage_h_)
+#define _EncoreBootImage_h_
+
+#include <list>
+#include <vector>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include "BootImage.h"
+#include "rijndael.h"
+#include "smart_ptr.h"
+#include "AESKey.h"
+#include "StExecutableImage.h"
+
+namespace elftosb
+{
+
+//! An AES-128 cipher block is 16 bytes.
+typedef uint8_t cipher_block_t[16];
+
+//! A SHA-1 digest is 160 bits, or 20 bytes.
+typedef uint8_t sha1_digest_t[20];
+
+//! Unique identifier type for a section.
+typedef uint32_t section_id_t;
+
+//! Utility to return the byte length of a number of cipher blocks.
+inline size_t sizeOfCipherBlocks(unsigned count) { return sizeof(cipher_block_t) * count; }
+
+//! Utility to return the number of cipher blocks required to hold an object
+//! that is \a s bytes long.
+inline size_t numberOfCipherBlocks(size_t s) { return (s + sizeof(cipher_block_t) - 1) / sizeof(cipher_block_t); }
+
+//! Utility to calculate the byte length for the cipher blocks required to hold
+//! and object that is \a bytes long.
+inline size_t sizeInCipherBlocks(size_t s) { return (unsigned)sizeOfCipherBlocks(numberOfCipherBlocks(s)); }
+
+//! Utility to return the number of bytes of padding required to fill out
+//! the last cipher block in a set of cipher blocks large enough to hold
+//! an object that is \a s bytes large. The result may be 0 if \a s is
+//! an even multiple of the cipher block size.
+inline size_t sizeOfPaddingForCipherBlocks(size_t s) { return sizeInCipherBlocks(s) - s; }
+
+/*!
+ * \brief Class to manage Encore boot image files.
+ *
+ * Initially this class will only support generation of boot images, but
+ * its design will facilitate the addition of the ability to read an
+ * image and examine its contents.
+ *
+ * A boot image is composed of the following regions:
+ * - Header
+ * - Section table
+ * - Key dictionary
+ * - Section data
+ * - Authentication
+ *
+ * Multiple sections are within a boot image are fully supported. Two general types
+ * of sections are supported with this class. Bootable sections, represented by the
+ * EncoreBootImage::BootSection class, contain a sequence of commands to be
+ * interpreted by the boot ROM. Data sections are represented by the
+ * EncoreBootImage::DataSection class and can contain any arbitrary data.
+ *
+ * An image can either be encrypted or unencrypted. The image uses a session key,
+ * or DEK (data encryption key), and the key dictionary to support any number of keys
+ * using a single image. The header and section table are always unencrypted even
+ * in encrypted images. This allows host utilities to access the individual
+ * sections without needing to have access to an encryption key.
+ *
+ * To construct a boot image, first create an instance of EncoreBootImage. Then
+ * create instances of the EncoreBootImage::BootSection or EncoreBootImage::DataSection
+ * for each of the sections in the image. For bootable sections, create and add
+ * the desired boot command objects. These are all subclasses of
+ * EncoreBootImage::BootCommand.
+ *
+ * If the boot image is to be encrypted, you need to add keys, which are instances
+ * of the AES128Key class. If no keys are added, the entire boot image will be unencrypted.
+ *
+ * When the image is fully constructed, it can be written to any std::ostream with
+ * a call to writeToStream(). The same image can be written to streams any
+ * number of times.
+ */
+class EncoreBootImage : public BootImage
+{
+public:
+       //! \brief Flag constants for the m_flags field of #elftosb::EncoreBootImage::boot_image_header_t.
+       enum
+       {
+               ROM_DISPLAY_PROGRESS = (1 << 0),                //!< Print progress reports.
+               ROM_VERBOSE_PROGRESS = (1 << 1)                 //!< Progress reports are verbose.
+       };
+       
+       enum {
+               ROM_IMAGE_HEADER_SIGNATURE = 'STMP',    //!< Signature in #elftosb::EncoreBootImage::boot_image_header_t::m_signature.
+               ROM_IMAGE_HEADER_SIGNATURE2 = 'sgtl',   //!< Value for #elftosb::EncoreBootImage::boot_image_header_t::m_signature2;
+               ROM_BOOT_IMAGE_MAJOR_VERSION = 1,               //!< Current boot image major version.
+               ROM_BOOT_IMAGE_MINOR_VERSION = 1                //!< Current boot image minor version.
+       };
+       
+       enum {
+               //! Minimum alignment for a section is 16 bytes.
+               BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT = sizeof(cipher_block_t)
+       };
+       
+// All of these structures are packed to byte alignment in order to match
+// the structure on disk.
+#pragma pack(1)
+       
+       //! \brief Header for the entire boot image.
+       //!
+       //! Fields of this header are arranged so that those used by the bootloader ROM all come
+       //! first. They are also set up so that all fields are not split across cipher block
+       //! boundaries. The fields not used by the bootloader are not subject to this
+       //! restraint.
+       //!
+       //! Image header size is always a round number of cipher blocks. The same also applies to
+       //! the boot image itself. The padding, held in #elftosb::EncoreBootImage::boot_image_header_t::m_padding0
+       //! and #elftosb::EncoreBootImage::boot_image_header_t::m_padding1 is filled with random bytes.
+       //!
+       //! The DEK dictionary, section table, and each section data region must all start on
+       //! cipher block boundaries.
+       //!
+       //! This header is not encrypted in the image file.
+       //!
+       //! The m_digest field contains a SHA-1 digest of the fields of the header that follow it.
+       //! It is the first field in the header so it doesn't change position or split the header
+       //! in two if fields are added to the header.
+       struct boot_image_header_t
+       {
+               union
+               {
+                       sha1_digest_t m_digest;         //!< SHA-1 digest of image header. Also used as the crypto IV.
+                       struct
+                       {
+                               cipher_block_t m_iv;    //!< The first 16 bytes of the digest form the initialization vector.
+                               uint8_t m_extra[4];             //!< The leftover top four bytes of the SHA-1 digest.
+                       };
+               };
+               uint8_t m_signature[4];                 //!< 'STMP', see #ROM_IMAGE_HEADER_SIGNATURE.
+               uint8_t m_majorVersion;                 //!< Major version for the image format, see #ROM_BOOT_IMAGE_MAJOR_VERSION.
+               uint8_t m_minorVersion;         //!< Minor version of the boot image format, see #ROM_BOOT_IMAGE_MINOR_VERSION.
+               uint16_t m_flags;                               //!< Flags or options associated with the entire image.
+               uint32_t m_imageBlocks;                 //!< Size of entire image in blocks.
+               uint32_t m_firstBootTagBlock;   //!< Offset from start of file to the first boot tag, in blocks.
+               section_id_t m_firstBootableSectionID;  //!< ID of section to start booting from.
+               uint16_t m_keyCount;                    //!< Number of entries in DEK dictionary.
+               uint16_t m_keyDictionaryBlock;  //!< Starting block number for the key dictionary.
+               uint16_t m_headerBlocks;                //!< Size of this header, including this size word, in blocks.
+               uint16_t m_sectionCount;                //!< Number of section headers in this table.
+               uint16_t m_sectionHeaderSize;   //!< Size in blocks of a section header.
+               uint8_t m_padding0[2];                  //!< Padding to align #m_timestamp to long word.
+               uint8_t m_signature2[4];                //!< Second signature to distinguish this .sb format from the 36xx format, see #ROM_IMAGE_HEADER_SIGNATURE2.
+               uint64_t m_timestamp;                   //!< Timestamp when image was generated in microseconds since 1-1-2000.
+               version_t m_productVersion;             //!< Product version.
+               version_t m_componentVersion;   //!< Component version.
+               uint16_t m_driveTag;                    //!< Drive tag for the system drive which this boot image belongs to.
+               uint8_t m_padding1[6];          //!< Padding to round up to next cipher block.
+       };
+
+       //! \brief Entry in #elftosb::EncoreBootImage::dek_dictionary_t.
+       //!
+       //! The m_dek field in each entry is encrypted using the KEK with the m_iv field from
+       //! the image header as the IV.
+       struct dek_dictionary_entry_t
+       {
+               cipher_block_t m_mac;                   //!< CBC-MAC of the header.
+               aes128_key_t m_dek;                             //!< AES-128 key with which the image payload is encrypted.
+       };
+
+       //! \brief The DEK dictionary always follows the image header, in the next cipher block.
+       struct dek_dictionary_t
+       {
+               dek_dictionary_entry_t m_entries[1];
+       };
+
+       //! \brief Section flags constants for the m_flags field of #elftosb::EncoreBootImage::section_header_t.
+       enum
+       {
+               ROM_SECTION_BOOTABLE = (1 << 0),        //!< The section contains bootloader commands.
+               ROM_SECTION_CLEARTEXT = (1 << 1)        //!< The section is unencrypted. Applies only if the rest of the boot image is encrypted.
+       };
+
+       //! \brief Information about each section, held in the section table.
+       //! \see section_table_t
+       struct section_header_t
+       {
+               uint32_t m_tag;                                 //!< Unique identifier for this section. High bit must be zero.
+               uint32_t m_offset;                              //!< Offset to section data from start of image in blocks.
+               uint32_t m_length;                              //!< Size of section data in blocks.
+               uint32_t m_flags;                               //!< Section flags.
+       };
+       
+       //! \brief An index of all sections within the boot image.
+       //!
+       //! The section table will be padded so that its length is divisible by 16 (if necessary).
+       //! Actually, each entry is padded to be a round number of cipher blocks, which
+       //! automatically makes this true for the entire table.
+       //!
+       //! Sections are ordered as they appear in this table, but are identified by the
+       //! #elftosb::EncoreBootImage::section_header_t::m_tag.
+       //!
+       //! The data for each section in encrypted separately with the DEK in CBC mode using
+       //! m_iv for the IV. This allows the ROM to jump to any given section without needing
+       //! to read the previous cipher block. In addition, the data for each section is
+       //! prefixed with a "boot tag", which describes the section which follows it. Boot
+       //! tags are the same format as a boot command, and are described by the
+       //! EncoreBootImage::TagCommand class.
+       //!
+       //! The section table starts immediately after the image header, coming before the
+       //! key dictionary (if present). The section table is not encrypted.
+       struct section_table_t
+       {
+               section_header_t m_sections[1]; //!< The table entries.
+       };
+
+       //! \brief Structure for a Piano bootloader command.
+       //!
+       //! Each command is composed of a fixed length header of 16 bytes. This happens to be
+       //! the size of a cipher block. Most commands will only require the header.
+       //!
+       //! But some commands, i.e. the "load data" command, may require additional arbitrary
+       //! amounts of data. This data is packed into the N cipher blocks that immediately
+       //! follow the command header. If the length of the data is not divisible by 16, then
+       //! random (not zero!) pad bytes will be added.
+       struct boot_command_t
+       {
+               uint8_t m_checksum;                             //!< Simple checksum over other command fields.
+               uint8_t m_tag;                                  //!< Tag telling which command this is.
+               uint16_t m_flags;                               //!< Flags for this command.
+               uint32_t m_address;                             //!< Target address.
+               uint32_t m_count;                               //!< Number of bytes on which to operate.
+               uint32_t m_data;                                //!< Additional data used by certain commands.
+       };
+
+#pragma pack()
+       
+       //! \brief Bootloader command tag constants.
+       enum
+       {
+               ROM_NOP_CMD = 0x00,             //!< A no-op command.
+               ROM_TAG_CMD = 0x01,             //!< Section tag command.
+               ROM_LOAD_CMD = 0x02,    //!< Load data command.
+               ROM_FILL_CMD = 0x03,    //!< Pattern fill command.
+               ROM_JUMP_CMD = 0x04,    //!< Jump to address command.
+               ROM_CALL_CMD = 0x05,    //!< Call function command.
+               ROM_MODE_CMD = 0x06             //!< Change boot mode command.
+       };
+       
+       //! \brief Flag field constants for #ROM_TAG_CMD.
+       enum
+       {
+               ROM_LAST_TAG = (1 << 0) //!< This tag command is the last one in the image.
+       };
+       
+       //! \brief Flag field constants for #ROM_LOAD_CMD.
+       enum
+       {
+               ROM_LOAD_DCD = (1 << 0) //!< Execute the DCD after loading completes.
+       };
+       
+       //! \brief Flag field constants for #ROM_FILL_CMD.
+       enum
+       {
+               ROM_FILL_BYTE = 0,              //!< Fill with byte sized pattern.
+               ROM_FILL_HALF_WORD = 1, //!< Fill with half-word sized pattern.
+               ROM_FILL_WORD = 2               //!< Fill with word sized pattern.
+       };
+       
+       //! brief Flag field constants for #ROM_JUMP_CMD and #ROM_CALL_CMD.
+       enum
+       {
+               ROM_HAB_EXEC = (1 << 0) //!< Changes jump or call command to a HAB jump or call.
+       };
+
+public:
+       // Forward declaration.
+       class Section;
+       
+       /*!
+        * \brief Base class for objects that produce cipher blocks.
+        */
+       class CipherBlockGenerator
+       {
+       public:
+       
+               //! \name Cipher blocks
+               //@{
+               //! \brief Returns the total number of cipher blocks.
+               //!
+               //! The default implementation returns 0, indicating that no blocks are
+               //! available.
+               virtual unsigned getBlockCount() const { return 0; }
+               
+               //! \brief Returns the contents of up to \a maxCount cipher blocks.
+               //!
+               //! Up to \a maxCount cipher blocks are copied into the buffer pointed to by
+               //! the \a data argument. This is only a request for \a maxCount blocks,
+               //! the subclass implementation of this method is free to return any number
+               //! of blocks from 0 up to \a maxCount. A return value of 0 indicates that
+               //! no more blocks are available. The index of the first block to copy is
+               //! held in the \a offset argument.
+               //!
+               //! \param offset Starting block number to copy. Zero means the first available block.
+               //! \param maxCount Up to this number of blocks may be copied into \a data. Must be 1 or greater.
+               //! \param data Buffer for outgoing cipher blocks. Must have enough room to hold
+               //!             \a maxCount blocks.
+               //!
+               //! \return The number of cipher blocks copied into \a data.
+               //! \retval 0 No more blocks are available and nothing was written to \a data.
+               virtual unsigned getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data) { return 0; }
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const {}
+       };
+       
+       /*!
+        * \brief Abstract base class for all bootloader commands.
+        */
+       class BootCommand : public CipherBlockGenerator
+       {
+       public:
+               //! \brief Creates the correct subclass of BootCommand for the given raw data.
+               static BootCommand * createFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed);
+               
+       public:
+               //! \brief Default constructor.
+               BootCommand() : CipherBlockGenerator() {}
+               
+               //! \brief Destructor.
+               virtual ~BootCommand() {}
+               
+               //! \brief Read the command contents from raw data.
+               //!
+               //! The subclass implementations should validate the contents of the command, including
+               //! the fields of the command header in the first block. It should be assumed that
+               //! only the tag field was examined to determine which subclass of BootCommand
+               //! should be created.
+               //!
+               //! \param blocks Pointer to the raw data blocks.
+               //! \param count Number of blocks pointed to by \a blocks.
+               //! \param[out] consumed On exit, this points to the number of cipher blocks that were occupied
+               //!             by the command. Should be at least 1 for every command. This must not be NULL
+               //!             on entry!
+               virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed)=0;
+               
+               //! \name Header
+               //@{
+               //! \brief Pure virtual method to return the tag value for this command.
+               virtual uint8_t getTag() const = 0;
+               
+               //! \brief Pure virtual method to construct the header for this boot command.
+               virtual void fillCommandHeader(boot_command_t & header) = 0;
+               
+               //! \brief Calculates the checksum for the given command header.
+               virtual uint8_t calculateChecksum(const boot_command_t & header);
+               //@}
+               
+               //! \name Cipher blocks
+               //@{
+               //! \brief Returns the total number of cipher blocks.
+               virtual unsigned getBlockCount() const;
+               
+               //! \brief Returns the contents of up to \a maxCount cipher blocks.
+               virtual unsigned getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data);
+               //@}
+               
+               //! \name Data blocks
+               //@{
+               //! \brief Returns the number of data cipher blocks that follow this command.
+               //!
+               //! The default implementation returns 0, indicating that no data blocks are
+               //! available.
+               virtual unsigned getDataBlockCount() const { return 0; }
+               
+               //! \brief Returns the contents of up to \a maxCount data blocks.
+               //!
+               //! Up to \a maxCount data blocks are copied into the buffer pointed to by
+               //! the \a data argument. This is only a request for \a maxCount blocks,
+               //! the subclass implementation of this method is free to return any number
+               //! of blocks from 0 up to \a maxCount. A return value of 0 indicates that
+               //! no more blocks are available. The index of the first block to copy is
+               //! held in the \a offset argument.
+               //!
+               //! \param offset Starting block number to copy. Zero means the first available block.
+               //! \param maxCount Up to this number of blocks may be copied into \a data. Must be 1 or greater.
+               //! \param data Buffer for outgoing data blocks. Must have enough room to hold
+               //!             \a maxCount blocks.
+               //!
+               //! \return The number of data blocks copied into \a data.
+               //! \retval 0 No more blocks are available and nothing was written to \a data.
+               virtual unsigned getDataBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data) { return 0; }
+               //@}
+       
+       protected:
+               //! The flag bit values for the \a whichFields parameter of validateHeader().
+               enum
+               {
+                       CMD_TAG_FIELD = 1,
+                       CMD_FLAGS_FIELD = 2,
+                       CMD_ADDRESS_FIELD = 4,
+                       CMD_COUNT_FIELD = 8,
+                       CMD_DATA_FIELD = 16
+               };
+
+               //! \brief
+               void validateHeader(const boot_command_t * modelHeader, const boot_command_t * testHeader, unsigned whichFields);
+       };
+       
+       /*!
+        * \brief No operation bootloader command.
+        */
+       class NopCommand : public BootCommand
+       {
+       public:
+               //! \brief Default constructor.
+               NopCommand() : BootCommand() {}
+               
+               //! \brief Read the command contents from raw data.
+               virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed);
+               
+               //! \name Header
+               //@{
+               //! \brief Returns the tag value for this command.
+               virtual uint8_t getTag() const { return ROM_NOP_CMD; }
+               
+               //! \brief Constructs the header for this boot command.
+               virtual void fillCommandHeader(boot_command_t & header);
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+       };
+       
+       /*!
+        * \brief Section tag bootloader command.
+        */
+       class TagCommand : public BootCommand
+       {
+       public:
+               //! \brief Default constructor.
+               TagCommand() : BootCommand() {}
+               
+               //! \brief Constructor taking a section object.
+               TagCommand(const Section & section);
+               
+               //! \brief Read the command contents from raw data.
+               virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed);
+               
+               //! \name Header
+               //@{
+               //! \brief Returns the tag value for this command.
+               virtual uint8_t getTag() const { return ROM_TAG_CMD; }
+               
+               //! \brief Constructs the header for this boot command.
+               virtual void fillCommandHeader(boot_command_t & header);
+               //@}
+               
+               //! \name Field accessors
+               //@{
+               inline void setSectionIdentifier(uint32_t identifier) { m_sectionIdentifier = identifier; }
+               inline void setSectionLength(uint32_t length) { m_sectionLength = length; }
+               inline void setSectionFlags(uint32_t flags) { m_sectionFlags = flags; }
+               inline void setLast(bool isLast) { m_isLast = isLast; }
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+               
+       protected:
+               uint32_t m_sectionIdentifier;   //!< Unique identifier for the section containing this command.
+               uint32_t m_sectionLength;       //!< Number of cipher blocks this section occupies.
+               uint32_t m_sectionFlags;        //!< Flags pertaining to this section.
+               bool m_isLast;  //!< Is this the last tag command?
+       };
+       
+       /*!
+        * \brief Load data bootloader command.
+        */
+       class LoadCommand : public BootCommand
+       {
+       public:
+               //! \brief Default constructor.
+               LoadCommand();
+               
+               //! \brief Constructor.
+               LoadCommand(uint32_t address, const uint8_t * data, uint32_t length);
+               
+               //! \brief Read the command contents from raw data.
+               virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed);
+               
+               //! \name Header
+               //@{
+               //! \brief Returns the tag value for this command.
+               virtual uint8_t getTag() const { return ROM_LOAD_CMD; }
+               
+               //! \brief Constructs the header for this boot command.
+               virtual void fillCommandHeader(boot_command_t & header);
+               
+               //! \brief Sets the load-dcd flag.
+               inline void setDCD(bool isDCD) { m_loadDCD = isDCD; }
+               //@}
+               
+               //! \name Address
+               //@{
+               inline void setLoadAddress(uint32_t address) { m_address = address; }
+               inline uint32_t getLoadAddress() const { return m_address; }
+               //@}
+               
+               //! \name Load data
+               //@{
+               //! \brief Set the data for the command to load.
+               void setData(const uint8_t * data, uint32_t length);
+               
+               inline uint8_t * getData() { return m_data; }
+               inline const uint8_t * getData() const { return m_data; }
+               inline uint32_t getLength() const { return m_length; }
+               //@}
+               
+               //! \name Data blocks
+               //@{
+               //! \brief Returns the number of data cipher blocks that follow this command.
+               virtual unsigned getDataBlockCount() const;
+               
+               //! \brief Returns the contents of up to \a maxCount data blocks.
+               virtual unsigned getDataBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data);
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+       
+       protected:
+               smart_array_ptr<uint8_t> m_data;        //!< Pointer to data to load.
+               uint8_t m_padding[15];  //!< Up to 15 pad bytes may be required.
+               unsigned m_padCount;    //!< Number of pad bytes.
+               uint32_t m_length;      //!< Number of bytes to load.
+               uint32_t m_address;     //!< Address to which data will be loaded.
+               bool m_loadDCD; //!< Whether to execute the DCD after loading.
+               
+               void fillPadding();
+               uint32_t calculateCRC() const;
+       };
+       
+       /*!
+        * \brief Pattern fill bootloader command.
+        */
+       class FillCommand : public BootCommand
+       {
+       public:
+               //! \brief Default constructor.
+               FillCommand();
+               
+               //! \brief Read the command contents from raw data.
+               virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed);
+               
+               //! \name Header
+               //@{
+               //! \brief Returns the tag value for this command.
+               virtual uint8_t getTag() const { return ROM_FILL_CMD; }
+               
+               //! \brief Constructs the header for this boot command.
+               virtual void fillCommandHeader(boot_command_t & header);
+               //@}
+               
+               //! \name Address range
+               //@{
+               inline void setAddress(uint32_t address) { m_address = address; };
+               inline uint32_t getAddress() const { return m_address; }
+               
+               inline void setFillCount(uint32_t count) { m_count = count; }
+               inline uint32_t getFillCount() const { return m_count; }
+               //@}
+               
+               //! \name Pattern
+               //@{
+               void setPattern(uint8_t pattern);
+               void setPattern(uint16_t pattern);
+               void setPattern(uint32_t pattern);
+               
+               inline uint32_t getPattern() const { return m_pattern; }
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+       
+       protected:
+               uint32_t m_address;     //!< Fill start address.
+               uint32_t m_count;       //!< Number of bytes to fill.
+               uint32_t m_pattern;     //!< Fill pattern.
+       };
+       
+       /*!
+        * \brief Change boot mode bootloader command.
+        */
+       class ModeCommand : public BootCommand
+       {
+       public:
+               //! \brief Default constructor.
+               ModeCommand() : BootCommand(), m_mode(0) {}
+               
+               //! \brief Read the command contents from raw data.
+               virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed);
+               
+               //! \name Header
+               //@{
+               //! \brief Returns the tag value for this command.
+               virtual uint8_t getTag() const { return ROM_MODE_CMD; }
+               
+               //! \brief Constructs the header for this boot command.
+               virtual void fillCommandHeader(boot_command_t & header);
+               //@}
+               
+               //! \name Boot mode
+               //@{
+               inline void setBootMode(uint32_t mode) { m_mode = mode; }
+               inline uint32_t getBootMode() const { return m_mode; }
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+       
+       protected:
+               uint32_t m_mode;        //!< New boot mode.
+       };
+       
+       /*!
+        * \brief Jump to address bootloader command.
+        */
+       class JumpCommand : public BootCommand
+       {
+       public:
+               //! \brief Default constructor.
+               JumpCommand() : BootCommand(), m_address(0), m_argument(0), m_isHAB(false), m_ivtSize(0) {}
+               
+               //! \brief Read the command contents from raw data.
+               virtual void initFromData(const cipher_block_t * blocks, unsigned count, unsigned * consumed);
+               
+               //! \name Header
+               //@{
+               //! \brief Returns the tag value for this command.
+               virtual uint8_t getTag() const { return ROM_JUMP_CMD; }
+               
+               //! \brief Constructs the header for this boot command.
+               virtual void fillCommandHeader(boot_command_t & header);
+               //@}
+               
+               //! \name Accessors
+               //@{
+               inline void setAddress(uint32_t address) { m_address = address; }
+               inline uint32_t getAddress() const { return m_address; }
+               
+               inline void setArgument(uint32_t argument) { m_argument = argument; }
+               inline uint32_t getArgument() const { return m_argument; }
+               
+               inline void setIsHAB(bool isHAB) { m_isHAB = isHAB; }
+               inline bool isHAB() const { return m_isHAB; }
+               
+               inline void setIVTSize(uint32_t ivtSize) { m_ivtSize = ivtSize; }
+               inline uint32_t getIVTSize() const { return m_ivtSize; }
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+               
+       protected:
+               uint32_t m_address;     //!< Address of the code to execute.
+               uint32_t m_argument;    //!< Sole argument to pass to code.
+               bool m_isHAB;           //!< Whether this jump/call is a special HAB jump/call. When this flag is set, m_address becomes the IVT address and m_ivtSize is the IVT size.
+               uint32_t m_ivtSize;     //!< Size of the IVT for a HAB jump/call.
+       };
+       
+       /*!
+        * \brief Call function bootloader command.
+        */
+       class CallCommand : public JumpCommand
+       {
+       public:
+               //! \brief Default constructor.
+               CallCommand() : JumpCommand() {}
+               
+               //! \brief Returns the tag value for this command.
+               virtual uint8_t getTag() const { return ROM_CALL_CMD; }
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+       };
+       
+       /*!
+        * \brief Base class for a section of an Encore boot image.
+        *
+        * Provides methods to manage the unique identifier that all sections have, and
+        * to set the boot image object which owns the section. There are also virtual
+        * methods to get header flags and fill in the header used in the section
+        * table. Subclasses must implement at least fillSectionHeader().
+        */
+       class Section : public CipherBlockGenerator
+       {
+       public:
+               //! \brief Default constructor.
+               Section() : CipherBlockGenerator(), m_identifier(0), m_image(0), m_alignment(BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT), m_flags(0), m_leaveUnencrypted(false) {}
+               
+               //! \brief Constructor taking the unique identifier for this section.
+               Section(uint32_t identifier) : CipherBlockGenerator(), m_identifier(identifier), m_image(0), m_alignment(BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT), m_flags(0), m_leaveUnencrypted(false) {}
+               
+               //! \name Identifier
+               //@{
+               inline void setIdentifier(uint32_t identifier) { m_identifier = identifier; }
+               inline uint32_t getIdentifier() const { return m_identifier; }
+               //@}
+               
+               //! \name Header
+               //@{
+               //! \brief Sets explicit flags for this section.
+               virtual void setFlags(uint32_t flags) { m_flags = flags; }
+               
+               //! \brief Returns the flags for this section.
+               //!
+               //! The return value consists of the flags set with setFlags() possibly or-ed
+               //! with #ROM_SECTION_CLEARTEXT if the section has been set to be left
+               //! unencrypted.
+               virtual uint32_t getFlags() const { return m_flags | ( m_leaveUnencrypted ? ROM_SECTION_CLEARTEXT : 0); }
+               
+               //! \brief Pure virtual method to construct the header for this section.
+               virtual void fillSectionHeader(section_header_t & header);
+               //@}
+               
+               //! \name Owner image
+               //@{
+               //! \brief Called when the section is added to an image.
+               void setImage(EncoreBootImage * image) { m_image = image; }
+               
+               //! \brief Returns a pointer to the image that this section belongs to.
+               EncoreBootImage * getImage() const { return m_image; }
+               //@}
+               
+               //! \name Alignment
+               //@{
+               //! \brief Sets the required alignment in the output file for this section.
+               void setAlignment(unsigned alignment);
+               
+               //! \brief Returns the current alignment, the minimum of which will be 16.
+               unsigned getAlignment() const { return m_alignment; }
+               
+               //! \brief Computes padding amount for alignment requirement.
+               unsigned getPadBlockCountForOffset(unsigned offset);
+               //@}
+               
+               //! \name Leave unencrypted flag
+               //@{
+               //! \brief Sets whether the section will be left unencrypted.
+               void setLeaveUnencrypted(unsigned flag) { m_leaveUnencrypted = flag; }
+               
+               //! \brief Returns true if the section will remain unencrypted.
+               bool getLeaveUnencrypted() const { return m_leaveUnencrypted; }
+               //@}
+       
+       protected:
+               uint32_t m_identifier;  //!< Unique identifier for this section.
+               EncoreBootImage * m_image;      //!< The image to which this section belongs.
+               unsigned m_alignment;   //!< Alignment requirement for the start of this section.
+               uint32_t m_flags;       //!< Section flags set by the user.
+               bool m_leaveUnencrypted;        //!< Set to true to prevent this section from being encrypted.
+       };
+       
+       /*!
+        * \brief A bootable section of an Encore boot image.
+        */
+       class BootSection : public Section
+       {
+       public:
+               typedef std::list<BootCommand*> command_list_t;
+               typedef command_list_t::iterator iterator_t;
+               typedef command_list_t::const_iterator const_iterator_t;
+               
+       public:
+               //! \brief Default constructor.
+               BootSection() : Section() {}
+               
+               //! \brief Constructor taking the unique identifier for this section.
+               BootSection(uint32_t identifier) : Section(identifier) {}
+               
+               //! \brief Destructor.
+               virtual ~BootSection();
+               
+               //! \brief Load the section from raw data.
+               virtual void fillFromData(const cipher_block_t * blocks, unsigned count);
+               
+               //! \name Header
+               //@{
+               //! \brief Returns the flags for this section.
+               virtual uint32_t getFlags() const { return Section::getFlags() | ROM_SECTION_BOOTABLE; }
+               //@}
+               
+               //! \name Commands
+               //@{
+               //! \brief Append a new command to the section.
+               //!
+               //! The section takes ownership of the command and will delete it when
+               //! the section is destroyed.
+               void addCommand(BootCommand * command) { m_commands.push_back(command); }
+               
+               //! \brief Returns the number of commands in this section, excluding the tag command.
+               unsigned getCommandCount() const { return (unsigned)m_commands.size(); }
+               
+               iterator_t begin() { return m_commands.begin(); }
+               iterator_t end() { return m_commands.end(); }
+               
+               const_iterator_t begin() const { return m_commands.begin(); }
+               const_iterator_t end() const { return m_commands.end(); }
+               //@}
+       
+               //! \name Cipher blocks
+               //@{
+               //! \brief Returns the total number of cipher blocks occupied by this section.
+               virtual unsigned getBlockCount() const;
+               
+               //! \brief Returns the contents of up to \a maxCount cipher blocks.
+               virtual unsigned getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data);
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+               
+       protected:
+               command_list_t m_commands;      //!< Commands held in this section.
+               
+       protected:
+               //! \brief Remove all commands from the section.
+               void deleteCommands();
+       };
+       
+       /*!
+        * \brief A non-bootable section of an Encore boot image.
+        */
+       class DataSection : public Section
+       {
+       public:
+               //! \brief Default constructor.
+               DataSection() : Section(), m_data(), m_length(0) {}
+               
+               //! \brief Constructor taking the unique identifier for this section.
+               DataSection(uint32_t identifier) : Section(identifier), m_data(), m_length(0) {}
+               
+               //! \brief Set the data section's contents.
+               void setData(const uint8_t * data, unsigned length);
+               
+               //! \brief Set the data section's contents without copying \a data.
+               void setDataNoCopy(const uint8_t * data, unsigned length);
+       
+               //! \name Cipher blocks
+               //@{
+               //! \brief Returns the total number of cipher blocks occupied by this section.
+               virtual unsigned getBlockCount() const;
+               
+               //! \brief Returns the contents of up to \a maxCount cipher blocks.
+               virtual unsigned getBlocks(unsigned offset, unsigned maxCount, cipher_block_t * data);
+               //@}
+               
+               //! \brief Print out a string representation of the object.
+               virtual void debugPrint() const;
+               
+       protected:
+               smart_array_ptr<uint8_t> m_data;        //!< The section's contents.
+               unsigned m_length;      //!< Number of bytes of data.
+       };
+
+public:
+       typedef std::list<Section*> section_list_t;                             //!< List of image sections.
+       typedef section_list_t::iterator section_iterator_t;    //!< Iterator over sections.
+       typedef section_list_t::const_iterator const_section_iterator_t;        //!< Const iterator over sections.
+       
+       typedef std::vector<AES128Key> key_list_t;                              //!< List of KEKs.
+       typedef key_list_t::iterator key_iterator_t;                    //!< Iterator over KEKs.
+       typedef key_list_t::const_iterator const_key_iterator_t;                        //!< Const iterator over KEKs.
+
+public:
+       //! \brief Default constructor.
+       EncoreBootImage();
+       
+       //! \brief Destructor.
+       virtual ~EncoreBootImage();
+       
+       //! \name Sections
+       //@{
+       void addSection(Section * newSection);
+       inline unsigned sectionCount() const { return (unsigned)m_sections.size(); }
+       
+       inline section_iterator_t beginSection() { return m_sections.begin(); }
+       inline section_iterator_t endSection() { return m_sections.end(); }
+       inline const_section_iterator_t beginSection() const { return m_sections.begin(); }
+       inline const_section_iterator_t endSection() const { return m_sections.end(); }
+       
+       section_iterator_t findSection(Section * section);
+       
+       //! \brief Calculates the starting block number for the given section.
+       uint32_t getSectionOffset(Section * section);
+       //@}
+       
+       //! \name Encryption keys
+       //@{
+       inline void addKey(const AES128Key & newKey) { m_keys.push_back(newKey); }
+       inline unsigned keyCount() const { return (unsigned)m_keys.size(); }
+
+       inline key_iterator_t beginKeys() { return m_keys.begin(); }
+       inline key_iterator_t endKeys() { return m_keys.end(); }
+       inline const_key_iterator_t beginKeys() const { return m_keys.begin(); }
+       inline const_key_iterator_t endKeys() const { return m_keys.end(); }
+       
+       //! \brief The image is encrypted if there is at least one key.
+       inline bool isEncrypted() const { return m_keys.size() != 0; }
+       //@}
+       
+       //! \name Versions
+       //@{
+       virtual void setProductVersion(const version_t & version);
+       virtual void setComponentVersion(const version_t & version);
+       //@}
+       
+       //! \name Flags
+       //@{
+       inline void setFlags(uint16_t flags) { m_headerFlags = flags; }
+       inline uint32_t getFlags() const { return m_headerFlags; }
+       //@}
+       
+       //! \brief Specify the drive tag to be set in the output file header.
+       virtual void setDriveTag(uint16_t tag) { m_driveTag = tag; }
+       
+       //! \brief Calculates the total number of cipher blocks the image consumes.
+       uint32_t getImageSize();
+       
+       //! \brief Returns the preferred ".sb" extension for Encore boot images.
+       virtual std::string getFileExtension() const { return ".sb"; }
+       
+       //! \name Output
+       //@{
+       //! \brief Write the boot image to an output stream.
+       virtual void writeToStream(std::ostream & stream);
+       //@}
+               
+       //! \brief Print out a string representation of the object.
+       virtual void debugPrint() const;
+       
+protected:
+       uint16_t m_headerFlags; //!< Flags field in the boot image header.
+       version_t m_productVersion;             //!< Product version.
+       version_t m_componentVersion;   //!< Component version.
+       uint16_t m_driveTag;    //!< System drive tag for this boot image.
+       section_list_t m_sections;      //!< Sections contained in this image.
+       key_list_t m_keys;      //!< List of key encryption keys. If empty, the image is unencrypted.
+       AES128Key m_sessionKey; //!< Session key we're using.
+       
+       void prepareImageHeader(boot_image_header_t & header);
+       uint64_t getTimestamp();
+       Section * findFirstBootableSection();
+       unsigned getPadBlockCountForSection(Section * section, unsigned offset);
+};
+
+}; // namespace elftosb
+
+#endif // _EncoreBootImage_h_
diff --git a/tools/elftosb/common/EndianUtilities.h b/tools/elftosb/common/EndianUtilities.h
new file mode 100644 (file)
index 0000000..f915309
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * File:       EndianUtilities.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_EndianUtilities_h_)
+#define _EndianUtilities_h_
+
+//! \name Swap macros
+//! These macros always swap the data.
+//@{
+
+//! Byte swap 16-bit value.
+#define _BYTESWAP16(value)                 \
+        (((((uint16_t)value)<<8) & 0xFF00)   | \
+         ((((uint16_t)value)>>8) & 0x00FF))
+
+//! Byte swap 32-bit value.
+#define _BYTESWAP32(value)                     \
+        (((((uint32_t)value)<<24) & 0xFF000000)  | \
+         ((((uint32_t)value)<< 8) & 0x00FF0000)  | \
+         ((((uint32_t)value)>> 8) & 0x0000FF00)  | \
+         ((((uint32_t)value)>>24) & 0x000000FF))
+
+//! Byte swap 64-bit value.
+#define _BYTESWAP64(value)                                \
+               (((((uint64_t)value)<<56) & 0xFF00000000000000ULL)  | \
+                ((((uint64_t)value)<<40) & 0x00FF000000000000ULL)  | \
+                ((((uint64_t)value)<<24) & 0x0000FF0000000000ULL)  | \
+                ((((uint64_t)value)<< 8) & 0x000000FF00000000ULL)  | \
+                ((((uint64_t)value)>> 8) & 0x00000000FF000000ULL)  | \
+                ((((uint64_t)value)>>24) & 0x0000000000FF0000ULL)  | \
+                ((((uint64_t)value)>>40) & 0x000000000000FF00ULL)  | \
+                ((((uint64_t)value)>>56) & 0x00000000000000FFULL))
+
+//@}
+
+//! \name Inline swap functions
+//@{
+
+inline uint16_t _swap_u16(uint16_t value) { return _BYTESWAP16(value); }
+inline int16_t _swap_s16(int16_t value) { return (int16_t)_BYTESWAP16((uint16_t)value); }
+
+inline uint32_t _swap_u32(uint32_t value) { return _BYTESWAP32(value); }
+inline int32_t _swap_s32(int32_t value) { return (int32_t)_BYTESWAP32((uint32_t)value); }
+
+inline uint64_t _swap_u64(uint64_t value) { return _BYTESWAP64(value); }
+inline int64_t _swap_s64(int64_t value) { return (uint64_t)_BYTESWAP64((uint64_t)value); }
+
+//@}
+
+#if defined(__LITTLE_ENDIAN__)
+
+       /* little endian host */
+
+       #define ENDIAN_BIG_TO_HOST_U16(value) (_swap_u16(value))
+       #define ENDIAN_HOST_TO_BIG_U16(value) (_swap_u16(value))
+       
+       #define ENDIAN_BIG_TO_HOST_S16(value) (_swap_s16(value))
+       #define ENDIAN_HOST_TO_BIG_S16(value) (_swap_s16(value))
+       
+       #define ENDIAN_BIG_TO_HOST_U32(value) (_swap_u32(value))
+       #define ENDIAN_HOST_TO_BIG_U32(value) (_swap_u32(value))
+       
+       #define ENDIAN_BIG_TO_HOST_S32(value) (_swap_s32(value))
+       #define ENDIAN_HOST_TO_BIG_S32(value) (_swap_s32(value))
+       
+       #define ENDIAN_BIG_TO_HOST_U64(value) (_swap_u64(value))
+       #define ENDIAN_HOST_TO_BIG_U64(value) (_swap_u64(value))
+       
+       #define ENDIAN_BIG_TO_HOST_S64(value) (_swap_s64(value))
+       #define ENDIAN_HOST_TO_BIG_S64(value) (_swap_s64(value))
+       
+       /* no-ops */
+       
+       #define ENDIAN_LITTLE_TO_HOST_U16(value) (value)
+       #define ENDIAN_HOST_TO_LITTLE_U16(value) (value)
+
+       #define ENDIAN_LITTLE_TO_HOST_S16(value) (value)
+       #define ENDIAN_HOST_TO_LITTLE_S16(value) (value)
+       
+       #define ENDIAN_LITTLE_TO_HOST_U32(value) (value)
+       #define ENDIAN_HOST_TO_LITTLE_U32(value) (value)
+       
+       #define ENDIAN_LITTLE_TO_HOST_S32(value) (value)
+       #define ENDIAN_HOST_TO_LITTLE_S32(value) (value)
+       
+       #define ENDIAN_LITTLE_TO_HOST_U64(value) (value)
+       #define ENDIAN_HOST_TO_LITTLE_U64(value) (value)
+       
+       #define ENDIAN_LITTLE_TO_HOST_S64(value) (value)
+       #define ENDIAN_HOST_TO_LITTLE_S64(value) (value)
+       
+#elif defined(__BIG_ENDIAN__)
+
+       /* big endian host */
+
+       #define ENDIAN_LITTLE_TO_HOST_U16(value) (_swap_u16(value))
+       #define ENDIAN_HOST_TO_LITTLE_U16(value) (_swap_u16(value))
+
+       #define ENDIAN_LITTLE_TO_HOST_S16(value) (_swap_s16(value))
+       #define ENDIAN_HOST_TO_LITTLE_S16(value) (_swap_s16(value))
+       
+       #define ENDIAN_LITTLE_TO_HOST_U32(value) (_swap_u32(value))
+       #define ENDIAN_HOST_TO_LITTLE_U32(value) (_swap_u32(value))
+       
+       #define ENDIAN_LITTLE_TO_HOST_S32(value) (_swap_s32(value))
+       #define ENDIAN_HOST_TO_LITTLE_S32(value) (_swap_s32(value))
+       
+       #define ENDIAN_LITTLE_TO_HOST_U64(value) (_swap_u64(value))
+       #define ENDIAN_HOST_TO_LITTLE_U64(value) (_swap_u64(value))
+       
+       #define ENDIAN_LITTLE_TO_HOST_S64(value) (_swap_s64(value))
+       #define ENDIAN_HOST_TO_LITTLE_S64(value) (_swap_s64(value))
+       
+       /* no-ops */
+       
+       #define ENDIAN_BIG_TO_HOST_U16(value) (value)
+       #define ENDIAN_HOST_TO_BIG_U16(value) (value)
+       
+       #define ENDIAN_BIG_TO_HOST_S16(value) (value)
+       #define ENDIAN_HOST_TO_BIG_S16(value) (value)
+       
+       #define ENDIAN_BIG_TO_HOST_U32(value) (value)
+       #define ENDIAN_HOST_TO_BIG_U32(value) (value)
+       
+       #define ENDIAN_BIG_TO_HOST_S32(value) (value)
+       #define ENDIAN_HOST_TO_BIG_S32(value) (value)
+       
+       #define ENDIAN_BIG_TO_HOST_U64(value) (value)
+       #define ENDIAN_HOST_TO_BIG_U64(value) (value)
+       
+       #define ENDIAN_BIG_TO_HOST_S64(value) (value)
+       #define ENDIAN_HOST_TO_BIG_S64(value) (value)
+
+#endif
+
+
+
+#endif // _EndianUtilities_h_
diff --git a/tools/elftosb/common/EvalContext.cpp b/tools/elftosb/common/EvalContext.cpp
new file mode 100644 (file)
index 0000000..876bb81
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * File:       EvalContext.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "EvalContext.h"
+#include <stdexcept>
+#include "format_string.h"
+
+using namespace elftosb;
+
+EvalContext::EvalContext()
+:      m_sourcesManager(0)
+{
+}
+
+EvalContext::~EvalContext()
+{
+}
+
+bool EvalContext::isVariableDefined(const std::string & name)
+{
+       variable_map_t::const_iterator it = m_variables.find(name);
+       return it != m_variables.end();
+}
+
+uint32_t EvalContext::getVariableValue(const std::string & name)
+{
+       variable_map_t::const_iterator it = m_variables.find(name);
+       if (it == m_variables.end())
+       {
+               throw std::runtime_error(format_string("undefined variable '%s'", name.c_str()));
+       }
+       
+       return it->second.m_value;
+}
+
+int_size_t EvalContext::getVariableSize(const std::string & name)
+{
+       variable_map_t::const_iterator it = m_variables.find(name);
+       if (it == m_variables.end())
+       {
+               throw std::runtime_error(format_string("undefined variable '%s'", name.c_str()));
+       }
+       
+       return it->second.m_size;
+}
+
+void EvalContext::setVariable(const std::string & name, uint32_t value, int_size_t size)
+{
+       // check if var is locked
+       variable_map_t::const_iterator it = m_variables.find(name);
+       if (it != m_variables.end() && it->second.m_isLocked)
+       {
+               return;
+       }
+       
+       // set var info
+       variable_info_t info;
+       info.m_value = value;
+       info.m_size = size;
+       info.m_isLocked = false;
+       m_variables[name] = info;
+}
+
+bool EvalContext::isVariableLocked(const std::string & name)
+{
+       variable_map_t::const_iterator it = m_variables.find(name);
+       if (it == m_variables.end())
+       {
+               throw std::runtime_error(format_string("undefined variable '%s'", name.c_str()));
+       }
+       
+       return it->second.m_isLocked;
+}
+
+void EvalContext::lockVariable(const std::string & name)
+{
+       variable_map_t::iterator it = m_variables.find(name);
+       if (it == m_variables.end())
+       {
+               throw std::runtime_error(format_string("undefined variable '%s'", name.c_str()));
+       }
+       
+       it->second.m_isLocked = true;
+}
+
+void EvalContext::unlockVariable(const std::string & name)
+{
+       variable_map_t::iterator it = m_variables.find(name);
+       if (it == m_variables.end())
+       {
+               throw std::runtime_error("undefined variable");
+       }
+       
+       it->second.m_isLocked = false;
+}
+
+void EvalContext::dump()
+{
+       variable_map_t::iterator it = m_variables.begin();
+       for (; it != m_variables.end(); ++it)
+       {
+               variable_info_t & info = it->second;
+               const char * lockedString = info.m_isLocked ? "locked" : "unlocked";
+               printf("%s = %u:%d (%s)\n", it->first.c_str(), info.m_value, (int)info.m_size, lockedString);
+       }
+}
+
diff --git a/tools/elftosb/common/EvalContext.h b/tools/elftosb/common/EvalContext.h
new file mode 100644 (file)
index 0000000..8c56d60
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * File:       EvalContext.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_EvalContext_h_)
+#define _EvalContext_h_
+
+#include <map>
+#include <string>
+#include "Value.h"
+#include "int_size.h"
+#include "SourceFile.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Context for evaluating AST tree and expressions.
+ *
+ * Keeps a map of variable names to integer values. Each integer value has a
+ * size attribute in addition to the actual value. Variables can be locked, which
+ * simply means that they cannot be assigned a new value.
+ *
+ * \todo Switch to using Value instances to keep track of variable values. This
+ *             will enable variables to have string values, for one.
+ */
+class EvalContext
+{
+public:
+       /*!
+        * \brief Abstract interface for a manager of source files.
+        */
+       class SourceFileManager
+       {
+       public:
+               //! \brief Returns true if a source file with the name \a name exists.
+               virtual bool hasSourceFile(const std::string & name)=0;
+               
+               //! \brief Gets the requested source file.
+               virtual SourceFile * getSourceFile(const std::string & name)=0;
+               
+               //! \brief Returns the default source file, or NULL if none is set.
+               virtual SourceFile * getDefaultSourceFile()=0;
+       };
+       
+public:
+       //! \brief Constructor.
+       EvalContext();
+       
+       //! \brief Destructor.
+       virtual ~EvalContext();
+       
+       //! \name Source file manager
+       //@{
+       //! \brief
+       void setSourceFileManager(SourceFileManager * manager) { m_sourcesManager = manager; }
+       
+       //! \brief
+       SourceFileManager * getSourceFileManager() { return m_sourcesManager; }
+       //@}
+       
+       //! \name Variables
+       //@{
+       bool isVariableDefined(const std::string & name);
+       uint32_t getVariableValue(const std::string & name);
+       int_size_t getVariableSize(const std::string & name);
+       void setVariable(const std::string & name, uint32_t value, int_size_t size=kWordSize);
+       //@}
+       
+       //! \name Locks
+       //@{
+       bool isVariableLocked(const std::string & name);
+       void lockVariable(const std::string & name);
+       void unlockVariable(const std::string & name);
+       //@}
+       
+       void dump();
+
+protected:
+       //! Information about a variable's value.
+       struct variable_info_t
+       {
+               uint32_t m_value;       //!< Variable value.
+               int_size_t m_size;      //!< Number of bytes
+               bool m_isLocked;        //!< Can this variable's value be changed?
+       };
+       
+       //! Type to maps between the variable name and its info.
+       typedef std::map<std::string, variable_info_t> variable_map_t;
+       
+       SourceFileManager * m_sourcesManager; //!< Interface to source file manager.
+       variable_map_t m_variables;     //!< Map of variables to their final values.
+};
+
+}; // namespace elftosb
+
+#endif // _EvalContext_h_
diff --git a/tools/elftosb/common/ExcludesListMatcher.cpp b/tools/elftosb/common/ExcludesListMatcher.cpp
new file mode 100644 (file)
index 0000000..56d67d6
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * File:       ExcludesListMatcher.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "ExcludesListMatcher.h"
+
+using namespace elftosb;
+
+ExcludesListMatcher::ExcludesListMatcher()
+:      GlobMatcher("")
+{
+}
+
+ExcludesListMatcher::~ExcludesListMatcher()
+{
+}
+
+//! \param isInclude True if this pattern is an include, false if it is an exclude.
+//! \param pattern String containing the glob pattern.
+void ExcludesListMatcher::addPattern(bool isInclude, const std::string & pattern)
+{
+       glob_list_item_t item;
+       item.m_isInclude = isInclude;
+       item.m_glob = pattern;
+       
+       // add to end of list
+       m_patterns.push_back(item);
+}
+
+//! If there are no entries in the match list, the match fails.
+//!
+//! \param testValue The string to match against the pattern list.
+//! \retval true The \a testValue argument matches.
+//! \retval false No match was made against the argument.
+bool ExcludesListMatcher::match(const std::string & testValue)
+{
+       if (!m_patterns.size())
+       {
+               return false;
+       }
+       
+       // Iterate over the match list. Includes act as an OR operator, while
+       // excludes act as an AND operator.
+       bool didMatch = false;
+       bool isFirstItem = true;
+       glob_list_t::iterator it = m_patterns.begin();
+       for (; it != m_patterns.end(); ++it)
+       {
+               glob_list_item_t & item = *it;
+               
+               // if this pattern is an include and it doesn't match, or
+               // if this pattern is an exclude and it does match, then the match fails
+               bool didItemMatch = globMatch(testValue.c_str(), item.m_glob.c_str());
+               
+               if (item.m_isInclude)
+               {
+                       // Include
+                       if (isFirstItem)
+                       {
+                               didMatch = didItemMatch;
+                       }
+                       else
+                       {
+                               didMatch = didMatch || didItemMatch;
+                       }
+               }
+               else
+               {
+                       // Exclude
+                       if (isFirstItem)
+                       {
+                               didMatch = !didItemMatch;
+                       }
+                       else
+                       {
+                               didMatch = didMatch && !didItemMatch;
+                       }
+               }
+               
+               isFirstItem = false;
+       }
+       
+       return didMatch;
+}
+
diff --git a/tools/elftosb/common/ExcludesListMatcher.h b/tools/elftosb/common/ExcludesListMatcher.h
new file mode 100644 (file)
index 0000000..31398a8
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * File:       ExcludesListMatcher.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_ExcludesListMatcher_h_)
+#define _ExcludesListMatcher_h_
+
+#include "GlobMatcher.h"
+#include <vector>
+#include <string>
+
+namespace elftosb
+{
+
+/*!
+ * \brief Matches strings using a series of include and exclude glob patterns.
+ *
+ * This string matcher class uses a sequential, ordered list of glob patterns to
+ * determine whether a string matches.  Attached to each pattern is an include/exclude
+ * action. The patterns in the list effectively form a Boolean expression. Includes
+ * act as an OR operator while excludes act as an AND NOT operator.
+ *
+ * Examples (plus prefix is include, minus prefix is exclude):
+ * - +foo: foo
+ * - -foo: !foo
+ * - +foo, +bar: foo || bar
+ * - +foo, -bar: foo && !bar
+ * - +foo, -bar, +baz: foo && !bar || baz
+ *
+ * The only reason for inheriting from GlobMatcher is so we can access the protected
+ * globMatch() method.
+ */
+class ExcludesListMatcher : public GlobMatcher
+{
+public:
+       //! \brief Default constructor.
+       ExcludesListMatcher();
+       
+       //! \brief Destructor.
+       ~ExcludesListMatcher();
+       
+       //! \name Pattern list
+       //@{
+       //! \brief Add one include or exclude pattern to the end of the match list.
+       void addPattern(bool isInclude, const std::string & pattern);
+       //@}
+       
+       //! \brief Performs a single string match test against testValue.
+       virtual bool match(const std::string & testValue);
+
+protected:
+       //! \brief Information about one glob pattern entry in a match list.
+       struct glob_list_item_t
+       {
+               bool m_isInclude;       //!< True if include, false if exclude.
+               std::string m_glob;     //!< The glob pattern to match.
+       };
+       
+       typedef std::vector<glob_list_item_t> glob_list_t;
+       glob_list_t m_patterns; //!< Ordered list of include and exclude patterns.
+};
+
+}; // namespace elftosb
+
+#endif // _ExcludesListMatcher_h_
diff --git a/tools/elftosb/common/GHSSecInfo.cpp b/tools/elftosb/common/GHSSecInfo.cpp
new file mode 100644 (file)
index 0000000..300366c
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * File:    GHSSecInfo.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "GHSSecInfo.h"
+#include <stdexcept>
+#include "Logging.h"
+#include "EndianUtilities.h"
+
+//! The name of the GHS-specific section info table ELF section.
+const char * const kSecInfoSectionName = ".secinfo";
+
+using namespace elftosb;
+
+//! The ELF file passed into this constructor as the \a elf argument must remain
+//! valid for the life of this object.
+//!
+//! \param elf The ELF file parser. An assertion is raised if this is NULL.
+GHSSecInfo::GHSSecInfo(StELFFile * elf)
+:      m_elf(elf), m_hasInfo(false), m_info(0), m_entryCount(0)
+{
+       assert(elf);
+       
+       // look up the section. if it's not there just leave m_info and m_entryCount to 0
+       unsigned sectionIndex = m_elf->getIndexOfSectionWithName(kSecInfoSectionName);
+       if (sectionIndex == SHN_UNDEF)
+       {
+               return;
+       }
+       
+       // get the section data
+       const Elf32_Shdr & secInfo = m_elf->getSectionAtIndex(sectionIndex);
+       if (secInfo.sh_type != SHT_PROGBITS)
+       {
+               // .secinfo section isn't the right type, so something is wrong
+               return;
+       }
+
+       m_hasInfo = true;
+       m_info = (ghs_secinfo_t *)m_elf->getSectionDataAtIndex(sectionIndex);
+       m_entryCount = secInfo.sh_size / sizeof(ghs_secinfo_t);
+}
+
+//! Looks up \a addr for \a length in the .secinfo array. Only if that address is in the
+//! .secinfo array does this section need to be filled. If the section is found but the
+//! length does not match the \a length argument, a message is logged at the
+//! #Logger::WARNING level.
+//!
+//! If the .secinfo section is not present in the ELF file, this method always returns
+//! true.
+//!
+//! \param addr The start address of the section to query.
+//! \param length The length of the section. If a section with a start address matching
+//!            \a addr is found, its length must match \a length to be considered.
+//!
+//! \retval true The section matching \a addr and \a length was found and should be filled.
+//!            True is also returned when the ELF file does not have a .secinfo section.
+//! \retval false The section was not found and should not be filled.
+bool GHSSecInfo::isSectionFilled(uint32_t addr, uint32_t length)
+{
+       if (!m_hasInfo)
+       {
+               return true;
+       }
+
+       unsigned i;
+       for (i = 0; i < m_entryCount; ++i)
+       {
+               // byte swap these values into host endianness
+               uint32_t clearAddr = ENDIAN_LITTLE_TO_HOST_U32(m_info[i].m_clearAddr);
+               uint32_t numBytesToClear = ENDIAN_LITTLE_TO_HOST_U32(m_info[i].m_numBytesToClear);
+               
+               // we only consider non-zero length clear regions
+               if ((addr == clearAddr) && (numBytesToClear != 0))
+               {
+                       // it is an error if the address matches but the length does not
+                       if (length != numBytesToClear)
+                       {
+                               Log::log(Logger::WARNING, "ELF Error: Size mismatch @ sect=%u, .secinfo=%u at addr 0x%08X\n", length, numBytesToClear, addr);
+                       }
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+//! Simply calls through to isSectionFilled(uint32_t, uint32_t) to determine
+//! if \a section should be filled.
+//!
+//! If the .secinfo section is not present in the ELF file, this method always returns
+//! true.
+bool GHSSecInfo::isSectionFilled(const Elf32_Shdr & section)
+{
+       return isSectionFilled(section.sh_addr, section.sh_size);
+}
+
diff --git a/tools/elftosb/common/GHSSecInfo.h b/tools/elftosb/common/GHSSecInfo.h
new file mode 100644 (file)
index 0000000..9042d39
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * File:    GHSSecInfo.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_GHSSecInfo_h_)
+#define _GHSSecInfo_h_
+
+#include "StELFFile.h"
+#include "smart_ptr.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Wrapper around the GHS-specific .secinfo ELF section.
+ *
+ * ELF files produced by the Green Hills MULTI toolset will have a
+ * special .secinfo section. For the most part, this section contains
+ * a list of address
+ * ranges that should be filled by the C runtime startup code. The
+ * address ranges correspond to those of ELF sections whose type is
+ * #SHT_NOBITS. The GHS runtime uses this table instead of just filling
+ * all #SHT_NOBITS sections because the linker command file can
+ * be used to optionally not fill individual sections.
+ *
+ * The isSectionFilled() methods let calling code determine if an ELF
+ * section is found in the .secinfo table. If the section is found,
+ * then it should be filled.
+ */
+class GHSSecInfo
+{
+public:
+       //! \brief Default constructor.
+       GHSSecInfo(StELFFile * elf);
+
+       //! \brief Returns true if there is a .secinfo section present in the ELF file.
+       bool hasSecinfo() const { return m_hasInfo; }
+       
+       //! \brief Determines if a section should be filled.
+       bool isSectionFilled(uint32_t addr, uint32_t length);
+       
+       //! \brief Determines if \a section should be filled.
+       bool isSectionFilled(const Elf32_Shdr & section);
+       
+protected:
+
+#pragma pack(1)
+
+       /*!
+        * \brief The structure of one .secinfo entry.
+        */
+       struct ghs_secinfo_t
+       {
+               uint32_t m_clearAddr;   //!< Address to start filling from.
+               uint32_t m_clearValue;  //!< Value to fill with.
+               uint32_t m_numBytesToClear;     //!< Number of bytes to fill.
+       };
+
+#pragma pack()
+
+protected:
+       StELFFile * m_elf;      //!< The parser object for our ELF file.
+       bool m_hasInfo;         //!< Whether .secinfo is present in the ELF file.
+       smart_array_ptr<ghs_secinfo_t> m_info;  //!< Pointer to the .secinfo entries. Will be NULL if there is no .secinfo section in the file.
+       unsigned m_entryCount;  //!< Number of entries in #m_info.
+};
+
+}; // namespace elftosb
+
+#endif // _GHSSecInfo_h_
diff --git a/tools/elftosb/common/GlobMatcher.cpp b/tools/elftosb/common/GlobMatcher.cpp
new file mode 100644 (file)
index 0000000..24e7b91
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * File:       GlobMatcher.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "GlobMatcher.h"
+
+#ifndef NEGATE
+#define NEGATE '^'                     // std cset negation char
+#endif
+
+using namespace elftosb;
+
+//! The glob pattern must match the \e entire test value argument in order
+//! for the match to be considered successful. Thus, even if, for example,
+//! the pattern matches all but the last character the result will be false.
+//!
+//! \retval true The test value does match the glob pattern.
+//! \retval false The test value does not match the glob pattern.
+bool GlobMatcher::match(const std::string & testValue)
+{
+       return globMatch(testValue.c_str(), m_pattern.c_str());
+}
+
+//! \note This glob implementation was originally written by ozan s. yigit in
+//!            December 1994. This is public domain source code.
+bool GlobMatcher::globMatch(const char *str, const char *p)
+{
+       int negate;
+       int match;
+       int c;
+
+       while (*p) {
+               if (!*str && *p != '*')
+                       return false;
+
+               switch (c = *p++) {
+
+               case '*':
+                       while (*p == '*')
+                               p++;
+
+                       if (!*p)
+                               return true;
+
+                       if (*p != '?' && *p != '[' && *p != '\\')
+                               while (*str && *p != *str)
+                                       str++;
+
+                       while (*str) {
+                               if (globMatch(str, p))
+                                       return true;
+                               str++;
+                       }
+                       return false;
+
+               case '?':
+                       if (*str)
+                               break;
+                       return false;
+               
+               // set specification is inclusive, that is [a-z] is a, z and
+               // everything in between. this means [z-a] may be interpreted
+               // as a set that contains z, a and nothing in between.
+               case '[':
+                       if (*p != NEGATE)
+                               negate = false;
+                       else {
+                               negate = true;
+                               p++;
+                       }
+
+                       match = false;
+
+                       while (!match && (c = *p++)) {
+                               if (!*p)
+                                       return false;
+                               if (*p == '-') {        // c-c
+                                       if (!*++p)
+                                               return false;
+                                       if (*p != ']') {
+                                               if (*str == c || *str == *p ||
+                                                   (*str > c && *str < *p))
+                                                       match = true;
+                                       }
+                                       else {          // c-]
+                                               if (*str >= c)
+                                                       match = true;
+                                               break;
+                                       }
+                               }
+                               else {                  // cc or c]
+                                       if (c == *str)
+                                               match = true;
+                                       if (*p != ']') {
+                                               if (*p == *str)
+                                                       match = true;
+                                       }
+                                       else
+                                               break;
+                               }
+                       }
+
+                       if (negate == match)
+                               return false;
+                       // if there is a match, skip past the cset and continue on
+                       while (*p && *p != ']')
+                               p++;
+                       if (!*p++)      // oops!
+                               return false;
+                       break;
+
+               case '\\':
+                       if (*p)
+                               c = *p++;
+               default:
+                       if (c != *str)
+                               return false;
+                       break;
+
+               }
+               str++;
+       }
+
+       return !*str;
+}
+
diff --git a/tools/elftosb/common/GlobMatcher.h b/tools/elftosb/common/GlobMatcher.h
new file mode 100644 (file)
index 0000000..c9e5641
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * File:       GlobMatcher.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_GlobMatcher_h_)
+#define _GlobMatcher_h_
+
+#include "StringMatcher.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief This class uses glob pattern matching to match strings.
+ *
+ * Glob patterns:
+ *     - *     matches zero or more characters
+ *     - ?     matches any single character
+ *     - [set] matches any character in the set
+ *     - [^set]        matches any character NOT in the set
+ *             where a set is a group of characters or ranges. a range
+ *             is written as two characters seperated with a hyphen: a-z denotes
+ *             all characters between a to z inclusive.
+ *     - [-set]        set matches a literal hypen and any character in the set
+ *     - []set]        matches a literal close bracket and any character in the set
+ *
+ *     - char  matches itself except where char is '*' or '?' or '['
+ *     - \\char        matches char, including any pattern character
+ *
+ * Examples:
+ *     - a*c           ac abc abbc ...
+ *     - a?c           acc abc aXc ...
+ *     - a[a-z]c               aac abc acc ...
+ *     - a[-a-z]c      a-c aac abc ...
+ */
+class GlobMatcher : public StringMatcher
+{
+public:
+       //! \brief Constructor.
+       GlobMatcher(const std::string & pattern)
+       :       StringMatcher(), m_pattern(pattern)
+       {
+       }
+       
+       //! \brief Returns whether \a testValue matches the glob pattern.
+       virtual bool match(const std::string & testValue);
+       
+protected:
+       std::string m_pattern;  //!< The glob pattern to match against.
+       
+       //! \brief Glob implementation.
+       bool globMatch(const char * str, const char * p);
+};
+
+}; // namespace elftosb
+
+#endif // _GlobMatcher_h_
diff --git a/tools/elftosb/common/HexValues.cpp b/tools/elftosb/common/HexValues.cpp
new file mode 100644 (file)
index 0000000..5eb2e39
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * File:       HexValues.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "HexValues.h"
+
+bool isHexDigit(char c)
+{
+       return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
+}
+
+//! \return The integer equivalent to \a c.
+//! \retval -1 The character \a c is not a hex character.
+uint8_t hexCharToInt(char c)
+{
+       if (c >= '0' && c <= '9')
+               return c - '0';
+       else if (c >= 'a' && c <= 'f')
+               return c - 'a' + 10;
+       else if (c >= 'A' && c <= 'F')
+               return c - 'A' + 10;
+       else
+               return static_cast<uint8_t>(-1);
+}
+
+//! \param encodedByte Must point to at least two ASCII hex characters.
+//!
+uint8_t hexByteToInt(const char * encodedByte)
+{
+       return (hexCharToInt(encodedByte[0]) << 4) | hexCharToInt(encodedByte[1]);
+}
diff --git a/tools/elftosb/common/HexValues.h b/tools/elftosb/common/HexValues.h
new file mode 100644 (file)
index 0000000..b6dd821
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * File:       HexValues.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_HexValues_h_)
+#define _HexValues_h_
+
+#include "stdafx.h"
+
+//! \brief Determines whether \a c is a hex digit character.
+bool isHexDigit(char c);
+
+//! \brief Converts a hexidecimal character to the integer equivalent.
+uint8_t hexCharToInt(char c);
+
+//! \brief Converts a hex-encoded byte to the integer equivalent.
+uint8_t hexByteToInt(const char * encodedByte);
+
+#endif // _HexValues_h_
diff --git a/tools/elftosb/common/IVTDataSource.cpp b/tools/elftosb/common/IVTDataSource.cpp
new file mode 100644 (file)
index 0000000..88c4753
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * File:       DataSource.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Freescale Semiconductor, Inc.
+ * Proprietary & Confidential
+ *
+ * This source code and the algorithms implemented therein constitute
+ * confidential information and may comprise trade secrets of Freescale Semiconductor, Inc.
+ * or its associates, and any use thereof is subject to the terms and
+ * conditions of the Confidential Disclosure Agreement pursual to which this
+ * source code was originally received.
+ */
+
+#include "IVTDataSource.h"
+#include "DataTarget.h"
+#include "EndianUtilities.h"
+#include <algorithm>
+#include <stdlib.h>
+#include <string.h>
+
+using namespace elftosb;
+
+IVTDataSource::IVTDataSource()
+:   DataSource(),
+    DataSource::Segment((DataSource&)*this),
+    m_isSelfSet(false)
+{
+    // Init the IVT structure.
+    memset(&m_ivt, 0, sizeof(m_ivt));
+    hab_hdr_t hdr = IVT_HDR(sizeof(m_ivt), HAB_VERSION);
+    m_ivt.hdr = hdr;
+}
+
+unsigned IVTDataSource::getData(unsigned offset, unsigned maxBytes, uint8_t * buffer)
+{
+    // Bail if the offset is out of range.
+    if (offset >= sizeof(m_ivt))
+    {
+        return 0;
+    }
+    
+    // If we have an associated target, and the IVT self pointer is not set, then
+    // fill in the self pointer from the target address.
+    if (m_target && !m_isSelfSet)
+    {
+        m_ivt.self = ENDIAN_HOST_TO_LITTLE_U32(m_target->getBeginAddress());
+    }
+    
+    // Truncate max bytes at the end of the IVT.
+    maxBytes = std::min<unsigned>(maxBytes, sizeof(m_ivt) - offset);
+    
+    // Copy into output buffer.
+    if (maxBytes)
+    {
+        memcpy(buffer, (uint8_t *)&m_ivt + offset, maxBytes);
+    }
+    
+    return maxBytes;
+}
+
+unsigned IVTDataSource::getLength()
+{
+    return sizeof(m_ivt);
+}
+
+//! The IVT has a natural location if its self pointer was explicitly specified.
+//!
+bool IVTDataSource::hasNaturalLocation()
+{
+    return m_isSelfSet;
+}
+
+//!
+uint32_t IVTDataSource::getBaseAddress()
+{
+    return m_ivt.self;
+}
+
+bool IVTDataSource::setFieldByName(const std::string & name, uint32_t value)
+{
+    if (name == "entry")
+    {
+        m_ivt.entry = ENDIAN_HOST_TO_LITTLE_U32(value);
+    }
+    else if (name == "dcd")
+    {
+        m_ivt.dcd = ENDIAN_HOST_TO_LITTLE_U32(value);
+    }
+    else if (name == "boot_data")
+    {
+        m_ivt.boot_data = ENDIAN_HOST_TO_LITTLE_U32(value);
+    }
+    else if (name == "self")
+    {
+        m_ivt.self = ENDIAN_HOST_TO_LITTLE_U32(value);
+        m_isSelfSet = true;
+    }
+    else if (name == "csf")
+    {
+        m_ivt.csf = ENDIAN_HOST_TO_LITTLE_U32(value);
+    }
+    else
+    {
+        // Unrecognized field name.
+        return false;
+    }
+    
+    return true;
+}
+
+
diff --git a/tools/elftosb/common/IVTDataSource.h b/tools/elftosb/common/IVTDataSource.h
new file mode 100644 (file)
index 0000000..1890bdd
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * File:       DataSource.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Freescale Semiconductor, Inc.
+ * Proprietary & Confidential
+ *
+ * This source code and the algorithms implemented therein constitute
+ * confidential information and may comprise trade secrets of Freescale Semiconductor, Inc.
+ * or its associates, and any use thereof is subject to the terms and
+ * conditions of the Confidential Disclosure Agreement pursual to which this
+ * source code was originally received.
+ */
+#if !defined(_IVTDataSource_h_)
+#define _IVTDataSource_h_
+
+#include "DataSource.h"
+
+/** Header field components
+ * @ingroup hdr
+ */
+typedef struct hab_hdr {
+    uint8_t tag;              /**< Tag field */
+    uint8_t len[2];           /**< Length field in bytes (big-endian) */
+    uint8_t par;              /**< Parameters field */
+} hab_hdr_t;
+
+/** Image entry function prototype
+ *  @ingroup rvt
+ *
+ * This typedef serves as the return type for hab_rvt.authenticate_image().  It
+ * specifies a void-void function pointer, but can be cast to another function
+ * pointer type if required.
+ */
+typedef void (*hab_image_entry_f)(void);
+
+/** @ref ivt structure
+ * @ingroup ivt
+ *
+ * @par Format
+ *
+ * An @ref ivt consists of a @ref hdr followed by a list of addresses as
+ * described further below.
+ *
+ * @warning The @a entry address may not be NULL.
+ *
+ * @warning On an IC not configured as #HAB_CFG_CLOSED, the
+ * @a csf address may be NULL.  If it is not NULL, the @ref csf will be
+ * processed, but any failures should be non-fatal.
+ *
+ * @warning On an IC configured as #HAB_CFG_CLOSED, the @a
+ * csf address may not be NULL, and @ref csf failures are typically fatal.
+ *
+ * @remark The Boot Data located using the @a boot_data field is interpreted
+ * by the HAB caller in a boot-mode specific manner.  This may be used by the
+ * boot ROM as to determine the load address and boot device configuration for
+ * images loaded from block devices (see @ref ref_rug for details).
+ *
+ * @remark All addresses given in the IVT, including the Boot Data (if
+ * present) are those for the final load location. 
+ *
+ * @anchor ila
+ *
+ * @par Initial load addresses
+ *
+ * The @a self field is used to calculate addresses in boot modes where an
+ * initial portion of the image is loaded to an initial location.  In such
+ * cases, the IVT, Boot Data (if present) and DCD (if present) are used in
+ * configuring the IC and loading the full image to its final location.  Only
+ * the IVT, Boot Data (if present) and DCD (if present) are required to be
+ * within the initial image portion.
+ *
+ * The method for calculating an initial load address for the DCD is
+ * illustrated in the following C fragment.  Similar calculations apply to
+ * other fields.
+ *
+@verbatim
+        hab_ivt_t* ivt_initial = <initial IVT load address>;
+        const void* dcd_initial = ivt_initial->dcd;
+        if (ivt_initial->dcd != NULL)
+            dcd_initial = (const uint8_t*)ivt_initial 
+                          + (ivt_initial->dcd - ivt_initial->self)
+@endverbatim
+
+ * \note The void* types in this structure have been changed to uint32_t so
+ *      that this code will work correctly when compiled on a 64-bit host.
+ *      Otherwise the structure would come out incorrect.
+ */
+struct hab_ivt {
+    /** @ref hdr with tag #HAB_TAG_IVT, length and HAB version fields
+     *  (see @ref data)
+     */
+    hab_hdr_t hdr;
+    /** Absolute address of the first instruction to execute from the
+     *  image
+     */
+    /*hab_image_entry_f*/ uint32_t entry;
+    /** Reserved in this version of HAB: should be NULL. */
+    /*const void*/ uint32_t reserved1;
+    /** Absolute address of the image DCD: may be NULL. */
+    /*const void*/ uint32_t dcd;
+    /** Absolute address of the Boot Data: may be NULL, but not interpreted
+     *  any further by HAB
+     */
+    /*const void*/ uint32_t boot_data;
+    /** Absolute address of the IVT.*/
+    /*const void*/ uint32_t self;
+    /** Absolute address of the image CSF.*/
+    /*const void*/ uint32_t csf;
+    /** Reserved in this version of HAB: should be zero. */
+    uint32_t reserved2;
+};
+
+/** @ref ivt type
+ * @ingroup ivt
+ */
+typedef struct hab_ivt hab_ivt_t;
+
+/*
+ *    Helper macros
+ */
+#define HAB_CMD_UNS     0xff
+
+#define DEFAULT_IMG_KEY_IDX     2
+
+#define GEN_MASK(width)                         \
+    ((1UL << (width)) - 1)
+
+#define GEN_FIELD(f, width, shift)              \
+    (((f) & GEN_MASK(width)) << (shift))
+
+#define PACK_UINT32(a, b, c, d)                 \
+    ( (((a) & 0xFF) << 24)                      \
+      |(((b) & 0xFF) << 16)                     \
+      |(((c) & 0xFF) << 8)                      \
+      |(((d) & 0xFF)) )
+
+#define EXPAND_UINT32(w)                                                \
+    (uint8_t)((w)>>24), (uint8_t)((w)>>16), (uint8_t)((w)>>8), (uint8_t)(w)
+
+#define HDR(tag, bytes, par)                                            \
+    (uint8_t)(tag), (uint8_t)((bytes)>>8), (uint8_t)(bytes), (uint8_t)(par)
+
+#define HAB_VER(maj, min)                                       \
+    (GEN_FIELD((maj), HAB_VER_MAJ_WIDTH, HAB_VER_MAJ_SHIFT)     \
+     | GEN_FIELD((min), HAB_VER_MIN_WIDTH, HAB_VER_MIN_SHIFT))
+
+/*
+ *    CSF header
+ */
+
+#define CSF_HDR(bytes, HABVER)                  \
+    HDR(HAB_TAG_CSF, (bytes), HABVER)
+    
+    
+/*
+ *    DCD  header
+ */
+
+#define DCD_HDR(bytes, HABVER)                  \
+    HDR(HAB_TAG_DCD, (bytes), HABVER)
+
+/*
+ *   IVT  header (goes in the struct's hab_hdr_t field, not a byte array)
+ */
+#define IVT_HDR(bytes, HABVER)                  \
+    {HAB_TAG_IVT, {(uint8_t)((bytes)>>8), (uint8_t)(bytes)}, HABVER}
+
+/** @name External data structure tags
+ * @anchor dat_tag
+ *
+ * Tag values 0x00 .. 0xef are reserved for HAB.  Values 0xf0 .. 0xff
+ * are available for custom use.
+ */
+/*@{*/
+#define HAB_TAG_IVT  0xd1       /**< Image Vector Table */
+#define HAB_TAG_DCD  0xd2       /**< Device Configuration Data */
+#define HAB_TAG_CSF  0xd4       /**< Command Sequence File */
+#define HAB_TAG_CRT  0xd7       /**< Certificate */
+#define HAB_TAG_SIG  0xd8       /**< Signature */
+#define HAB_TAG_EVT  0xdb       /**< Event */
+#define HAB_TAG_RVT  0xdd       /**< ROM Vector Table */
+/* Values b0 ... cf reserved for CSF commands.  Values e0 ... ef reserved for
+ * key types.
+ *
+ * Available values: 03, 05, 06, 09, 0a, 0c, 0f, 11, 12, 14, 17, 18, 1b, 1d,
+ * 1e, 21, 22, 24, 27, 28, 2b, 2d, 2e, 30, 33, 35, 36, 39, 3a, 3c, 3f, 41, 42,
+ * 44, 47, 48, 4b, 4d, 4e, 50, 53, 55, 56, 59, 5a, 5c, 5f, 60, 63, 65, 66, 69,
+ * 6a, 6c, 6f, 71, 72, 74, 77, 78, 7b, 7d, 7e, 81, 82, 84, 87, 88, 8b, 8d, 8e,
+ * 90, 93, 95, 96, 99, 9a, 9c, 9f, a0, a3, a5, a6, a9, aa, ac, af, b1, b2, b4,
+ * b7, b8, bb, bd, be
+ *
+ * Custom values: f0, f3, f5, f6, f9, fa, fc, ff
+ */
+/*@}*/
+
+/** @name HAB version */
+/*@{*/
+#define HAB_MAJOR_VERSION  4    /**< Major version of this HAB release */
+#define HAB_MINOR_VERSION  0    /**< Minor version of this HAB release */
+#define HAB_VER_MAJ_WIDTH 4     /**< Major version field width  */
+#define HAB_VER_MAJ_SHIFT 4     /**< Major version field offset  */
+#define HAB_VER_MIN_WIDTH 4     /**< Minor version field width  */
+#define HAB_VER_MIN_SHIFT 0     /**< Minor version field offset  */
+/** Full version of this HAB release @hideinitializer */
+#define HAB_VERSION HAB_VER(HAB_MAJOR_VERSION, HAB_MINOR_VERSION) 
+/** Base version for this HAB release @hideinitializer */
+#define HAB_BASE_VERSION HAB_VER(HAB_MAJOR_VERSION, 0) 
+
+/*@}*/
+
+namespace elftosb {
+
+/*!
+ * \brief Data source for an IVT structure used by HAB4.
+ *
+ * This data source represents an IVT structure used by HAB4. Fields of the IVT can be set
+ * by name, making it easy to interface with a parser. And it has some intelligence regarding
+ * the IVT's self pointer. Before the data is copied out by the getData() method, the self field
+ * will be filled in automatically if it has not already been set and there is an associated
+ * data target object. This lets the IVT pick up its own address from the location where it is
+ * being loaded. Alternatively, if the self pointer is filled in explicitly, then the data
+ * source will have a natural location equal to the self pointer.
+ *
+ * This data source acts as its own segment.
+ */
+class IVTDataSource : public DataSource, public DataSource::Segment
+{
+public:
+    //! \brief Default constructor.
+    IVTDataSource();
+    
+       //! \brief There is only one segment.
+       virtual unsigned getSegmentCount() { return 1; }
+       
+       //! \brief Returns this object, as it is its own segment.
+       virtual DataSource::Segment * getSegmentAt(unsigned index) { return this; }
+
+    //! \name Segment methods
+    //@{
+    
+    //! \brief Copy out some or all of the IVT structure.
+    //!
+    virtual unsigned getData(unsigned offset, unsigned maxBytes, uint8_t * buffer);
+    
+    //! \brief Gets the length of the segment's data.
+    virtual unsigned getLength();
+    
+    //! \brief Returns whether the segment has an associated address.
+    virtual bool hasNaturalLocation();
+    
+    //! \brief Returns the address associated with the segment.
+    virtual uint32_t getBaseAddress();
+    
+    //@}
+    
+    //! \name IVT access
+    //@{
+    
+    //! \brief Set one of the IVT's fields by providing its name.
+    //!
+    //! Acceptable field names are:
+    //! - entry
+    //! - dcd
+    //! - boot_data
+    //! - self
+    //! - csf
+    //!
+    //! As long as the \a name parameter specifies one of these fields, the return value
+    //! will be true. If \a name contains any other value, then false will be returned and
+    //! the IVT left unmodified.
+    //!
+    //! Once the \a self field has been set to any value, the data source will have a
+    //! natural location. This works even if the \a self address is 0.
+    //!
+    //! \param name The name of the field to set. Field names are case sensitive, just like in
+    //!     the C language.
+    //! \param value The value to which the field will be set.
+    //! \retval true The field was set successfully.
+    //! \retval false There is no field with the provided name.
+    bool setFieldByName(const std::string & name, uint32_t value);
+    
+    //! \brief Returns a reference to the IVT structure.
+    hab_ivt_t & getIVT() { return m_ivt; }
+    
+    //@}
+
+protected:
+    hab_ivt_t m_ivt;  //!< The IVT structure.
+    bool m_isSelfSet; //!< True if the IVT self pointer was explicitly set.
+};
+
+} // elftosb
+
+#endif // _IVTDataSource_h_
diff --git a/tools/elftosb/common/Logging.cpp b/tools/elftosb/common/Logging.cpp
new file mode 100644 (file)
index 0000000..f6d3906
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * File:       Logging.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "Logging.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include "smart_ptr.h"
+
+// init global logger to null
+Logger * Log::s_logger = NULL;
+
+void Logger::log(const char * fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       log(m_level, fmt, args);
+       va_end(args);
+}
+
+void Logger::log(log_level_t level, const char * fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       log(level, fmt, args);
+       va_end(args);
+}
+
+void Logger::log(const char * fmt, va_list args)
+{
+       log(m_level, fmt, args);
+}
+
+//! Allocates a temporary 1KB buffer which is used to hold the
+//! formatted string.
+void Logger::log(log_level_t level, const char * fmt, va_list args)
+{
+       smart_array_ptr<char> buffer = new char[1024];
+       vsprintf(buffer, fmt, args);
+       if (level <= m_filter)
+       {
+               _log(buffer);
+       }
+}
+
+void Log::log(const char * fmt, ...)
+{
+       if (s_logger)
+       {
+               va_list args;
+               va_start(args, fmt);
+               s_logger->log(fmt, args);
+               va_end(args);
+       }
+}
+
+void Log::log(const std::string & msg)
+{
+       if (s_logger)
+       {
+               s_logger->log(msg);
+       }
+}
+
+void Log::log(Logger::log_level_t level, const char * fmt, ...)
+{
+       if (s_logger)
+       {
+               va_list args;
+               va_start(args, fmt);
+               s_logger->log(level, fmt, args);
+               va_end(args);
+       }
+}
+
+void Log::log(Logger::log_level_t level, const std::string & msg)
+{
+       if (s_logger)
+       {
+               s_logger->log(level, msg);
+       }
+}
+
+void StdoutLogger::_log(const char * msg)
+{
+       printf(msg);
+}
+
diff --git a/tools/elftosb/common/Logging.h b/tools/elftosb/common/Logging.h
new file mode 100644 (file)
index 0000000..a8e7bed
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * File:       Logging.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_Logging_h_)
+#define _Logging_h_
+
+#include <string>
+#include <assert.h>
+#include <stdarg.h>
+
+/*!
+ * \brief Base logger class.
+ *
+ * There are two types of logging levels that are used by this class. First
+ * there is the filter level. Any log message that is assigned a level
+ * higher than the current filter level is discarded. Secondly there is the
+ * current output level. Log messages that do not have their own level
+ * use the current output level to determine if they should be shown or
+ * not.
+ *
+ * The two methods setFilterLevel() and setOutputLevel() set the filter
+ * and default output logging levels, respectively. There are corresponding
+ * getter methods as well. Both the filter and output levels are
+ * initialized to #INFO during object construction.
+ *
+ * Most use of the logger classes is expected to be through the Log
+ * class. It provides static logging methods that call through to a global
+ * singleton logger instance. There is also a Log::SetOutputLevel utility
+ * class that makes it extremely easiy to temporarily change the default
+ * output logging level.
+ *
+ * Of all the overloaded log() methods in this class, none of them are
+ * really expected to be reimplemented by subclasses. Instead, there is
+ * the single protected _log() method that takes a simple string pointer.
+ * The other log methods all wind up calling _log(), so it provides a
+ * single point to override. In fact, _log() is pure virtual, so subclasses
+ * must implement it.
+ *
+ * \see Log
+ */
+class Logger
+{
+public:
+       //! \brief Logging levels.
+       enum log_level_t
+       {
+               URGENT = 0,     //!< The lowest level, for messages that must always be logged.
+               ERROR,          //!< For fatal error messages.
+               WARNING,        //!< For non-fatal warning messages.
+               INFO,           //!< The normal log level, for status messages.
+               INFO2,          //!< For verbose status messages.
+               DEBUG,          //!< For internal reporting.
+               DEBUG2          //!< Highest log level; verbose debug logging.
+       };
+       
+public:
+       //! \brief Default constructor.
+       Logger() : m_filter(INFO), m_level(INFO) {}
+       
+       //! \brief Destructor.
+       virtual ~Logger() {}
+       
+       //! \name Logging levels
+       //@{
+       //! \brief Changes the logging level to \a level.
+       inline void setFilterLevel(log_level_t level) { m_filter = level; }
+       
+       //! \brief Returns the current logging filter level.
+       inline log_level_t getFilterLevel() const { return m_filter; }
+       
+       //! \brief Changes the logging output level to \a level.
+       inline void setOutputLevel(log_level_t level) { m_level = level; }
+       
+       //! \brief Returns the current logging output level.
+       inline log_level_t getOutputLevel() const { return m_level; }
+       //@}
+       
+       //! \name Logging
+       //@{
+       //! \brief Log with format.
+       virtual void log(const char * fmt, ...);
+       
+       //! \brief Log a string object.
+       virtual void log(const std::string & msg) { log(msg.c_str()); }
+       
+       //! \brief Log with format at a specific output level.
+       virtual void log(log_level_t level, const char * fmt, ...);
+       
+       //! \brief Log a string output at a specific output level.
+       virtual void log(log_level_t level, const std::string & msg) { log(level, msg.c_str()); }
+       
+       //! \brief Log with format using an argument list.
+       virtual void log(const char * fmt, va_list args);
+       
+       //! \brief Log with format using an argument with a specific output level.
+       virtual void log(log_level_t level, const char * fmt, va_list args);
+       //@}
+               
+protected:
+       log_level_t m_filter;   //!< The current logging filter level.
+       log_level_t m_level;    //!< The current log output level.
+       
+protected:
+       //! \brief The base pure virtual logging function implemented by subclasses.
+       virtual void _log(const char * msg)=0;
+};
+
+/*!
+ * \brief Wraps a set of static functions for easy global logging access.
+ *
+ * This class has a set of static methods that make it easy to access a global
+ * logger instance without having to worry about extern symbols. It does this
+ * by keeping a static member variable pointing at the singleton logger instance,
+ * which is set with the setLogger() static method.
+ *
+ * There is also an inner utility class called SetOutputLevel that uses
+ * C++ scoping rules to temporarily change the output logging level. When the
+ * SetOutputLevel instance falls out of scope the output level is restored
+ * to the previous value.
+ */
+class Log
+{
+public:
+       //! \name Singleton logger access
+       //@{
+       //! \brief Returns the current global logger singleton.
+       static inline Logger * getLogger() { return s_logger; }
+       
+       //! \brief Sets the global logger singleton instance.
+       static inline void setLogger(Logger * logger) { s_logger = logger; }
+       //@}
+       
+       //! \name Logging
+       //@{
+       //! \brief Log with format.
+       static void log(const char * fmt, ...);
+       
+       //! \brief Log a string object.
+       static void log(const std::string & msg);
+       
+       //! \brief Log with format at a specific output level.
+       static void log(Logger::log_level_t level, const char * fmt, ...);
+       
+       //! \brief Log a string output at a specific output level.
+       static void log(Logger::log_level_t level, const std::string & msg);
+       //@}
+       
+protected:
+       static Logger * s_logger;       //!< The single global logger instance.
+       
+public:
+       /*!
+        * \brief Utility class to temporarily change the logging output level.
+        *
+        * This class will change the current logging output level of a given
+        * logger instance. Then when it falls out of scope it will set the
+        * level back to what it was originally.
+        *
+        * Use like this:
+        * \code
+        *              // output level is some value here
+        *              {
+        *                      Log::SetOutputLevel leveler(Logger::DEBUG);
+        *                      // now output level is DEBUG
+        *                      Log::log("my debug message 1");
+        *                      Log::log("my debug message 2");
+        *              }
+        *              // output level is restored to previous value
+        * \endcode
+        */
+       class SetOutputLevel
+       {
+       public:
+               //! \brief Default constructor.
+               //!
+               //! Saves the current logging output level of the global logger,
+               //! as managed by the Log class, and sets the new level to \a level.
+               SetOutputLevel(Logger::log_level_t level)
+               :       m_logger(Log::getLogger()), m_saved(Logger::INFO)
+               {
+                       assert(m_logger);
+                       m_saved = m_logger->getOutputLevel();
+                       m_logger->setOutputLevel(level);
+               }
+               
+               //! \brief Constructor.
+               //!
+               //! Saves the current logging output level of \a logger and sets
+               //! the new level to \a level.
+               SetOutputLevel(Logger * logger, Logger::log_level_t level)
+               :       m_logger(logger), m_saved(logger->getOutputLevel())
+               {
+                       assert(m_logger);
+                       m_logger->setOutputLevel(level);
+               }
+               
+               //! \brief Destructor.
+               //!
+               //! Restores the saved logging output level.
+               ~SetOutputLevel()
+               {
+                       m_logger->setOutputLevel(m_saved);
+               }
+               
+       protected:
+               Logger * m_logger;      //!< The logger instance we're controlling.
+               Logger::log_level_t m_saved;    //!< Original logging output level.
+       };
+
+};
+
+
+/*!
+ * \brief Simple logger that writes to stdout.
+ */
+class StdoutLogger : public Logger
+{
+protected:
+       //! \brief Logs the message to stdout.
+       virtual void _log(const char * msg);
+};
+
+#endif // _Logging_h_
diff --git a/tools/elftosb/common/Operation.cpp b/tools/elftosb/common/Operation.cpp
new file mode 100644 (file)
index 0000000..79fd6d4
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * File:       Operation.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "Operation.h"
+
+using namespace elftosb;
+
+//! The operation object takes ownership of \a source.
+//!
+//! Cross references between the target and source are updated.
+void LoadOperation::setSource(DataSource * source)
+{
+       m_source = source;
+       
+       if (m_target)
+       {
+               m_target->setSource(m_source);
+       }
+       if (m_source)
+       {
+               m_source->setTarget(m_target);
+       }
+}
+
+//! The operation object takes ownership of \a target.
+//!
+//! Cross references between the target and source are updated.
+void LoadOperation::setTarget(DataTarget * target)
+{
+       m_target = target;
+       
+       if (m_target)
+       {
+               m_target->setSource(m_source);
+       }
+       if (m_source)
+       {
+               m_source->setTarget(m_target);
+       }
+}
+
+//! Disposes of operations objects in the sequence.
+OperationSequence::~OperationSequence()
+{
+//     iterator_t it = begin();
+//     for (; it != end(); ++it)
+//     {
+//             delete it->second;
+//     }
+}
+
+void OperationSequence::append(const OperationSequence * other)
+{
+       const_iterator_t it = other->begin();
+       for (; it != other->end(); ++it)
+       {
+               m_operations.push_back(*it);
+       }
+}
diff --git a/tools/elftosb/common/Operation.h b/tools/elftosb/common/Operation.h
new file mode 100644 (file)
index 0000000..2b184e3
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * File:       Operation.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_Operation_h_)
+#define _Operation_h_
+
+#include "stdafx.h"
+#include <vector>
+#include "DataSource.h"
+#include "DataTarget.h"
+#include "smart_ptr.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Abstract base class for all boot operations.
+ */
+class Operation
+{
+public:
+       Operation() {}
+       virtual ~Operation() {}
+};
+
+/*!
+ * \brief Load data into memory operation.
+ */
+class LoadOperation : public Operation
+{
+public:
+       LoadOperation() : Operation(), m_source(), m_target() {}
+       
+       void setSource(DataSource * source);
+       inline DataSource * getSource() { return m_source; }
+       
+       void setTarget(DataTarget * target);
+       inline DataTarget * getTarget() { return m_target; }
+       
+       inline void setDCDLoad(bool isDCD) { m_isDCDLoad = isDCD; }
+       inline bool isDCDLoad() const { return m_isDCDLoad; }
+       
+protected:
+       smart_ptr<DataSource> m_source;
+       smart_ptr<DataTarget> m_target;
+       bool m_isDCDLoad;
+};
+
+/*!
+ * \brief Operation to execute code at a certain address.
+ */
+class ExecuteOperation : public Operation
+{
+public:
+       enum execute_type_t
+       {
+               kJump,
+               kCall
+       };
+       
+public:
+       ExecuteOperation() : Operation(), m_target(), m_argument(0), m_type(kCall), m_isHAB(false) {}
+
+       inline void setTarget(DataTarget * target) { m_target = target; }
+       inline DataTarget * getTarget() { return m_target; }
+       
+       inline void setArgument(uint32_t arg) { m_argument = arg; }
+       inline uint32_t getArgument() { return m_argument; }
+       
+       inline void setExecuteType(execute_type_t type) { m_type = type; }
+       inline execute_type_t getExecuteType() { return m_type; }
+       
+       inline void setIsHAB(bool isHAB) { m_isHAB = isHAB; }
+       inline bool isHAB() const { return m_isHAB; }
+       
+protected:
+       smart_ptr<DataTarget> m_target;
+       uint32_t m_argument;
+       execute_type_t m_type;
+       bool m_isHAB;
+};
+
+/*!
+ * \brief Authenticate with HAB and execute the entry point.
+ */
+class HABExecuteOperation : public ExecuteOperation
+{
+public:
+       HABExecuteOperation() : ExecuteOperation() {}
+};
+
+/*!
+ * \brief Operation to switch boot modes.
+ */
+class BootModeOperation : public Operation
+{
+public:
+       BootModeOperation() : Operation() {}
+       
+       inline void setBootMode(uint32_t mode) { m_bootMode = mode; }
+       inline uint32_t getBootMode() const { return m_bootMode; }
+
+protected:
+       uint32_t m_bootMode;    //!< The new boot mode value.
+};
+
+/*!
+ * \brief Ordered sequence of operations.
+ *
+ * The operation objects owned by the sequence are \e not deleted when the
+ * sequence is destroyed. The owner of the sequence must manually delete
+ * the operation objects.
+ */
+class OperationSequence
+{
+public:
+       typedef std::vector<Operation*> operation_list_t;       //!< Type for a list of operation objects.
+       typedef operation_list_t::iterator iterator_t;  //!< Iterator over operations.
+       typedef operation_list_t::const_iterator const_iterator_t;      //!< Const iterator over operations.
+
+public:
+       //! \brief Default constructor.
+       OperationSequence() {}
+       
+       //! \brief Constructor. Makes a one-element sequence from \a soleElement.
+       OperationSequence(Operation * soleElement) { m_operations.push_back(soleElement); }
+       
+       //! \brief Destructor.
+       virtual ~OperationSequence();
+       
+       //! \name Iterators
+       //@{
+       inline iterator_t begin() { return m_operations.begin(); }
+       inline const_iterator_t begin() const { return m_operations.begin(); }
+       inline iterator_t end() { return m_operations.end(); }
+       inline const_iterator_t end() const { return m_operations.end(); }
+       //@}
+       
+       inline Operation * operator [] (unsigned index) const { return m_operations[index]; }
+       
+       //! \name Status
+       //@{
+       //! \brief Returns the number of operations in the sequence.
+       inline unsigned getCount() const { return m_operations.size(); }
+       //@}
+       
+       //! \name Operations
+       //@{
+       //! \brief Append one operation object to the sequence.
+       inline void append(Operation * op) { m_operations.push_back(op); }
+       
+       //! \brief Append the contents of \a other onto this sequence.
+       void append(const OperationSequence * other);
+       
+       //! \brief Appends \a other onto this sequence.
+       OperationSequence & operator += (const OperationSequence * other) { append(other); return *this; }
+       //@}
+
+protected:
+       operation_list_t m_operations;  //!< The list of operations.
+};
+
+}; // namespace elftosb
+
+#endif // _Operation_h_
diff --git a/tools/elftosb/common/OptionContext.h b/tools/elftosb/common/OptionContext.h
new file mode 100644 (file)
index 0000000..d005164
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * File:       OptionContext.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_OptionContext_h_)
+#define _OptionContext_h_
+
+#include <string>
+#include "Value.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Pure abstract interface class to a table of options.
+ */
+class OptionContext
+{
+public:        
+       //! \brief Detemine whether the named option is present in the table.
+       //! \param name The name of the option to query.
+       //! \retval true The option is present and has a value.
+       //! \retval false No option with that name is in the table.
+       virtual bool hasOption(const std::string & name) const=0;
+       
+       //! \brief Returns the option's value.
+       //! \param name The name of the option.
+       //! \return The value for the option named \a name.
+       //! \retval NULL No option is in the table with that name.
+       virtual const Value * getOption(const std::string & name) const=0;
+       
+       //! \brief Adds or changes an option's value.
+       //!
+       //! If the option was not already present in the table, it is added.
+       //! Otherwise the old value is replaced.
+       //!
+       //! \param name The option's name.
+       //! \param value New value for the option.
+       virtual void setOption(const std::string & name, Value * value)=0;
+       
+       //! \brief Removes an option from the table.
+       //! \param name The name of the option to remove.
+       virtual void deleteOption(const std::string & name)=0;
+};
+
+}; // namespace elftosb
+
+#endif // _OptionContext_h_
diff --git a/tools/elftosb/common/OptionDictionary.cpp b/tools/elftosb/common/OptionDictionary.cpp
new file mode 100644 (file)
index 0000000..a9acec7
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * File:       OptionDictionary.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "OptionDictionary.h"
+
+using namespace elftosb;
+
+//! Deletes all of the option values that have been assigned locally.
+//!
+OptionDictionary::~OptionDictionary()
+{
+       option_map_t::iterator it = m_options.begin();
+       for (; it != m_options.end(); ++it)
+       {
+               if (it->second.m_value)
+               {
+                       delete it->second.m_value;
+               }
+       }
+}
+
+//! If a parent context has been set and the option does not exist in
+//! this instance, then the parent is asked if it contains the option.
+//!
+//! \param name The name of the option to query.
+//! \retval true The option is present in this instance or one of the parent.
+//! \retval false No option with that name is in the dictionary, or any parent
+bool OptionDictionary::hasOption(const std::string & name) const
+{
+       bool hasIt = (m_options.find(name) != m_options.end());
+       if (!hasIt && m_parent)
+       {
+               return m_parent->hasOption(name);
+       }
+       return hasIt;
+}
+
+//! If this object does not contain an option with the name of \a name,
+//! then the parent is asked for the value (if a parent has been set).
+//!
+//! \param name The name of the option.
+//! \return The value for the option named \a name.
+//! \retval NULL No option is in the table with that name. An option may also
+//!            explicitly be set to a NULL value. The only way to tell the difference
+//!            is to use the hasOption() method.
+const Value * OptionDictionary::getOption(const std::string & name) const
+{
+       option_map_t::const_iterator it = m_options.find(name);
+       if (it == m_options.end())
+       {
+               if (m_parent)
+               {
+                       return m_parent->getOption(name);
+               }
+               else
+               {
+                       return NULL;
+               }
+       }
+       
+       return it->second.m_value;
+}
+
+//! If the option was not already present in the table, it is added.
+//! Otherwise the old value is replaced. The option is always set locally;
+//! parent objects are never modified.
+//!
+//! If the option has been locked with a call to lockOption() before trying
+//! to set its value, the setOption() is effectively ignored. To tell if
+//! an option is locked, use the isOptionLocked() method.
+//!
+//! \warning If the option already had a value, that previous value is deleted.
+//!            This means that it cannot currently be in use by another piece of code.
+//!            See the note in getOption().
+//!
+//! \param name The option's name.
+//! \param value New value for the option.
+void OptionDictionary::setOption(const std::string & name, Value * value)
+{
+       option_map_t::iterator it = m_options.find(name);
+       OptionValue newValue;
+
+       // delete the option value instance before replacing it
+       if (it != m_options.end())
+       {
+               // Cannot modify value if locked.
+               if (it->second.m_isLocked)
+               {
+                       return;
+               }
+
+               if (it->second.m_value)
+               {
+                       delete it->second.m_value;
+               }
+
+               // save previous locked value
+               newValue.m_isLocked = it->second.m_isLocked;
+       }
+       
+       // set new option value
+       newValue.m_value = value;
+       m_options[name] = newValue;
+}
+
+//! \param name The name of the option to remove.
+//!
+void OptionDictionary::deleteOption(const std::string & name)
+{
+       if (m_options.find(name) != m_options.end())
+       {
+               if (m_options[name].m_value)
+               {
+                       delete m_options[name].m_value;
+               }
+               m_options.erase(name);
+       }
+}
+
+//! \param name Name of the option to query.
+//!
+//! \return True if the option is locked, false if unlocked or not present.
+//!
+bool OptionDictionary::isOptionLocked(const std::string & name) const
+{
+       option_map_t::const_iterator it = m_options.find(name);
+       if (it != m_options.end())
+       {
+               return it->second.m_isLocked;
+       }
+
+       return false;
+}
+
+//! \param name Name of the option to lock.
+//!
+void OptionDictionary::lockOption(const std::string & name)
+{
+       if (!hasOption(name))
+       {
+               m_options[name].m_value = 0;
+       }
+
+       m_options[name].m_isLocked = true;
+}
+
+//! \param name Name of the option to unlock.
+//!
+void OptionDictionary::unlockOption(const std::string & name)
+{
+       if (!hasOption(name))
+       {
+               m_options[name].m_value = 0;
+       }
+
+       m_options[name].m_isLocked = false;
+}
+
+
+//! Simply calls getOption().
+//!
+const Value * OptionDictionary::operator [] (const std::string & name) const
+{
+       return getOption(name);
+}
+
diff --git a/tools/elftosb/common/OptionDictionary.h b/tools/elftosb/common/OptionDictionary.h
new file mode 100644 (file)
index 0000000..275bd01
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * File:       OptionDictionary.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_OptionDictionary_h_)
+#define _OptionDictionary_h_
+
+#include "OptionContext.h"
+#include <map>
+
+namespace elftosb
+{
+
+/*!
+ * \brief Concrete implementation of OptionContext.
+ *
+ * This context subclass supports having a parent context. If an option is not
+ * found in the receiving instance, the request is passed to the parent.
+ * The hasOption() and getOption() methods will ask up the parent chain
+ * if the requested option does not exist in the receiving instance.
+ * But the setOption() and deleteOption() methods only operate locally,
+ * on the instance on which they were called. This allows a caller to
+ * locally override an option value without affecting any of the parent
+ * contexts.
+ */
+class OptionDictionary : public OptionContext
+{
+public:
+       //! \brief Default constructor.
+       OptionDictionary() : m_parent(0) {}
+       
+       //! \brief Constructor taking a parent context.
+       OptionDictionary(OptionContext * parent) : m_parent(parent) {}
+       
+       //! \brief Destructor.
+       ~OptionDictionary();
+       
+       //! \name Parents
+       //@{
+       //! \brief Returns the current parent context.
+       //! \return The current parent context instance.
+       //! \retval NULL No parent has been set.
+       inline OptionContext * getParent() const { return m_parent; }
+       
+       //! \brief Change the parent context.
+       //! \param newParent The parent context object. May be NULL, in which case
+       //!             the object will no longer have a parent context.
+       inline void setParent(OptionContext * newParent) { m_parent = newParent; }
+       //@}
+       
+       //! \name Options
+       //@{
+       //! \brief Detemine whether the named option is present in the table.
+       virtual bool hasOption(const std::string & name) const;
+       
+       //! \brief Returns the option's value.
+       virtual const Value * getOption(const std::string & name) const;
+       
+       //! \brief Adds or changes an option's value.
+       virtual void setOption(const std::string & name, Value * value);
+       
+       //! \brief Removes an option from the table.
+       virtual void deleteOption(const std::string & name);
+       //@}
+
+       //! \name Locking
+       //@{
+       //! \brief Returns true if the specified option is locked from further changes.
+       bool isOptionLocked(const std::string & name) const;
+
+       //! \brief Prevent further modifications of an option's value.
+       void lockOption(const std::string & name);
+
+       //! \brief Allow an option to be changed.
+       void unlockOption(const std::string & name);
+       //@}
+       
+       //! \name Operators
+       //@{
+       //! \brief Indexing operator; returns the value for the option \a name.
+       const Value * operator [] (const std::string & name) const;
+       //@}
+       
+protected:
+       OptionContext * m_parent;       //!< Our parent context.
+
+       /*!
+        * \brief Information about one option's value.
+        */
+       struct OptionValue
+       {
+               Value * m_value;        //!< The object for this option's value.
+               bool m_isLocked;        //!< True if this value is locked from further changes.
+
+               //! \brief Constructor.
+               OptionValue() : m_value(0), m_isLocked(false) {}
+       };
+       
+       typedef std::map<std::string, OptionValue> option_map_t;        //!< Map from option name to value.
+       option_map_t m_options; //!< The option dictionary.
+};
+
+}; // namespace elftosb
+
+#endif // _OptionDictionary_h_
diff --git a/tools/elftosb/common/OutputSection.cpp b/tools/elftosb/common/OutputSection.cpp
new file mode 100644 (file)
index 0000000..a6cb622
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * File:       OutputSection.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "OutputSection.h"
+
diff --git a/tools/elftosb/common/OutputSection.h b/tools/elftosb/common/OutputSection.h
new file mode 100644 (file)
index 0000000..702a52b
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * File:       OutputSection.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_OutputSection_h_)
+#define _OutputSection_h_
+
+#include "Operation.h"
+#include "smart_ptr.h"
+#include "Blob.h"
+#include "OptionContext.h"
+
+namespace elftosb
+{
+
+/*!
+ * @brief Base class for data model of sections of the output file.
+ */
+class OutputSection
+{
+public:
+       OutputSection() : m_id(0), m_options(0) {}
+       OutputSection(uint32_t identifier) : m_id(identifier), m_options(0) {}
+       virtual ~OutputSection() {}
+       
+       void setIdentifier(uint32_t identifier) { m_id = identifier; }
+       uint32_t getIdentifier() const { return m_id; }
+       
+       //! \brief Set the option context.
+       //!
+       //! The output section object will assume ownership of the option context
+       //! and delete it when the section is deleted.
+       inline void setOptions(OptionContext * context) { m_options = context; }
+       
+       //! \brief Return the option context.
+       inline const OptionContext * getOptions() const { return m_options; }
+       
+protected:
+       uint32_t m_id;  //!< Unique identifier.
+       smart_ptr<OptionContext> m_options;     //!< Options associated with just this section.
+};
+
+/*!
+ * @brief A section of the output that contains boot operations.
+ */
+class OperationSequenceSection : public OutputSection
+{
+public:
+       OperationSequenceSection() : OutputSection() {}
+       OperationSequenceSection(uint32_t identifier) : OutputSection(identifier) {}
+       
+       OperationSequence & getSequence() { return m_sequence; }
+
+protected:
+       OperationSequence m_sequence;
+};
+
+/*!
+ * @brief A section of the output file that contains arbitrary binary data.
+ */
+class BinaryDataSection : public OutputSection, public Blob
+{
+public:
+       BinaryDataSection() : OutputSection(), Blob() {}
+       BinaryDataSection(uint32_t identifier) : OutputSection(identifier), Blob() {}
+};
+
+}; // namespace elftosb
+
+#endif // _OutputSection_h_
diff --git a/tools/elftosb/common/Random.cpp b/tools/elftosb/common/Random.cpp
new file mode 100644 (file)
index 0000000..e9785aa
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * File:       Random.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "Random.h"
+#include <stdexcept>
+
+#ifdef WIN32
+       #ifndef _WIN32_WINNT
+               #define _WIN32_WINNT 0x0400
+       #endif
+       #include <windows.h>
+       #include <wincrypt.h>
+#else  // WIN32
+       #include <errno.h>
+       #include <fcntl.h>
+       #include <unistd.h>
+#endif // WIN32
+
+
+
+#ifdef WIN32
+
+MicrosoftCryptoProvider::MicrosoftCryptoProvider()
+{
+       if(!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+       {
+               throw std::runtime_error("CryptAcquireContext");
+       }
+}
+
+MicrosoftCryptoProvider::~MicrosoftCryptoProvider()
+{
+       CryptReleaseContext(m_hProvider, 0);
+}
+
+#endif // WIN32
+
+RandomNumberGenerator::RandomNumberGenerator()
+{
+#ifndef WIN32
+       m_fd = open("/dev/urandom",O_RDONLY);
+       if (m_fd == -1)
+       {
+               throw std::runtime_error("open /dev/urandom");
+       }
+#endif // WIN32
+}
+
+RandomNumberGenerator::~RandomNumberGenerator()
+{
+#ifndef WIN32
+       close(m_fd);
+#endif // WIN32
+}
+
+uint8_t RandomNumberGenerator::generateByte()
+{
+       uint8_t result;
+       generateBlock(&result, 1);
+       return result;
+}
+
+void RandomNumberGenerator::generateBlock(uint8_t * output, unsigned count)
+{
+#ifdef WIN32
+#      ifdef WORKAROUND_MS_BUG_Q258000
+               static MicrosoftCryptoProvider m_provider;
+#      endif
+       if (!CryptGenRandom(m_provider.GetProviderHandle(), count, output))
+       {
+               throw std::runtime_error("CryptGenRandom");
+       }
+#else  // WIN32
+       if (read(m_fd, output, count) != count)
+       {
+               throw std::runtime_error("read /dev/urandom");
+       }
+#endif // WIN32
+}
+
+
diff --git a/tools/elftosb/common/Random.h b/tools/elftosb/common/Random.h
new file mode 100644 (file)
index 0000000..5aac6ab
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * File:       Random.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_Random_h_)
+#define _Random_h_
+
+#include "stdafx.h"
+
+#ifdef WIN32
+/*!
+ * This class is from the crypto++ library.
+ */
+class MicrosoftCryptoProvider
+{
+public:
+       MicrosoftCryptoProvider();
+       ~MicrosoftCryptoProvider();
+#if defined(_WIN64)
+       typedef unsigned __int64 ProviderHandle;        // type HCRYPTPROV, avoid #include <windows.h>
+#else
+       typedef unsigned long ProviderHandle;
+#endif
+       ProviderHandle GetProviderHandle() const {return m_hProvider;}
+private:
+       ProviderHandle m_hProvider;
+};
+
+#pragma comment(lib, "advapi32.lib")
+#endif // WIN32
+
+/*!
+ * Encapsulates the Windows CryptoAPI's CryptGenRandom or /dev/urandom on Unix systems.
+ */
+class RandomNumberGenerator
+{
+public:
+       RandomNumberGenerator();
+       ~RandomNumberGenerator();
+       
+       uint8_t generateByte();
+       void generateBlock(uint8_t * output, unsigned count);
+
+protected:
+#ifdef WIN32
+#      ifndef WORKAROUND_MS_BUG_Q258000
+               MicrosoftCryptoProvider m_provider;
+#      endif
+#else  // WIN32
+       int m_fd;
+#endif // WIN32
+};
+
+
+#endif // _Random_h_
diff --git a/tools/elftosb/common/RijndaelCBCMAC.cpp b/tools/elftosb/common/RijndaelCBCMAC.cpp
new file mode 100644 (file)
index 0000000..fad0339
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * File:       RijndaelCBCMAC.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "RijndaelCBCMAC.h"
+#include "rijndael.h"
+#include <assert.h>
+#include "Logging.h"
+
+void logHexArray(Logger::log_level_t level, const uint8_t * bytes, unsigned count);
+
+//! \param key The key to use as the CBC-MAC secret.
+//! \param iv Initialization vector. Defaults to zero if not provided.
+RijndaelCBCMAC::RijndaelCBCMAC(const AESKey<128> & key, const uint8_t * iv)
+:      m_key(key)
+{
+       if (iv)
+       {
+               memcpy(m_mac, iv, sizeof(m_mac));
+       }
+       else
+       {
+               memset(m_mac, 0, sizeof(m_mac));
+       }
+}
+
+//! \param data Pointer to data to process.
+//! \param length Number of bytes to process. Must be evenly divisible by #BLOCK_SIZE.
+void RijndaelCBCMAC::update(const uint8_t * data, unsigned length)
+{
+       assert(length % BLOCK_SIZE == 0);
+       unsigned blocks = length / BLOCK_SIZE;
+       while (blocks--)
+       {
+               updateOneBlock(data);
+               data += BLOCK_SIZE;
+       }
+}
+
+//! It appears that some forms of CBC-MAC encrypt the final output block again in
+//! order to protect against a plaintext attack. This method is a placeholder for
+//! such an operation, but it currently does nothing.
+void RijndaelCBCMAC::finalize()
+{
+}
+
+//! On entry the current value of m_mac becomes the initialization vector
+//! for the CBC encryption of this block. The output of the encryption then
+//! becomes the new MAC, which is stored in m_mac.
+void RijndaelCBCMAC::updateOneBlock(const uint8_t * data)
+{
+       Rijndael cipher;
+       cipher.init(Rijndael::CBC, Rijndael::Encrypt, m_key, Rijndael::Key16Bytes, m_mac);
+       cipher.blockEncrypt(data, BLOCK_SIZE * 8, m_mac);       // size is in bits
+       
+//     Log::log(Logger::DEBUG2, "CBC-MAC output block:\n");
+//     logHexArray(Logger::DEBUG2, (const uint8_t *)&m_mac, sizeof(m_mac));
+}
+
+/*!
+ * \brief Log an array of bytes as hex.
+ */
+void logHexArray(Logger::log_level_t level, const uint8_t * bytes, unsigned count)
+{
+       Log::SetOutputLevel leveler(level);
+//             Log::log("    ");
+       unsigned i;
+       for (i = 0; i < count; ++i, ++bytes)
+       {
+               if ((i % 16 == 0) && (i < count - 1))
+               {
+                       if (i != 0)
+                       {
+                               Log::log("\n");
+                       }
+                       Log::log("    0x%04x: ", i);
+               }
+               Log::log("%02x ", *bytes & 0xff);
+       }
+       
+       Log::log("\n");
+}
+
diff --git a/tools/elftosb/common/RijndaelCBCMAC.h b/tools/elftosb/common/RijndaelCBCMAC.h
new file mode 100644 (file)
index 0000000..97e1f47
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * File:       RijndaelCBCMAC.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_RijndaelCBCMAC_h_)
+#define _RijndaelCBCMAC_h_
+
+#include "AESKey.h"
+#include <string.h>
+
+/*!
+ * \brief Class to compute CBC-MAC using the AES/Rijndael cipher.
+ *
+ * Currently only supports 128-bit keys and block sizes.
+ */
+class RijndaelCBCMAC
+{
+public:
+       enum
+       {
+               BLOCK_SIZE = 16 //!< Number of bytes in one cipher block.
+       };
+       
+       //! The cipher block data type.
+       typedef uint8_t block_t[BLOCK_SIZE];
+       
+public:
+       //! \brief Default constructor.
+       //!
+       //! The key and IV are both set to zero.
+       RijndaelCBCMAC() {}
+       
+       //! \brief Constructor.
+       RijndaelCBCMAC(const AESKey<128> & key, const uint8_t * iv=0);
+       
+       //! \brief Process data.
+       void update(const uint8_t * data, unsigned length);
+       
+       //! \brief Signal that all data has been processed.
+       void finalize();
+       
+       //! \brief Returns a reference to the current MAC value.
+       const block_t & getMAC() const { return m_mac; }
+       
+       //! \brief Assignment operator.
+       RijndaelCBCMAC & operator = (const RijndaelCBCMAC & other)
+       {
+               m_key = other.m_key;
+               memcpy(m_mac, other.m_mac, sizeof(m_mac));
+               return *this;
+       }
+       
+protected:
+       AESKey<128> m_key;      //!< 128-bit key to use for the CBC-MAC.
+       block_t m_mac;  //!< Current message authentication code value.
+       
+       void updateOneBlock(const uint8_t * data);
+};
+
+#endif // _RijndaelCBCMAC_h_
diff --git a/tools/elftosb/common/SHA1.cpp b/tools/elftosb/common/SHA1.cpp
new file mode 100644 (file)
index 0000000..93b9a99
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+       100% free public domain implementation of the SHA-1 algorithm
+       by Dominik Reichl <dominik.reichl@t-online.de>
+       Web: http://www.dominik-reichl.de/
+
+       Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
+       - You can set the endianness in your files, no need to modify the
+         header file of the CSHA1 class any more
+       - Aligned data support
+       - Made support/compilation of the utility functions (ReportHash
+         and HashFile) optional (useful, if bytes count, for example in
+         embedded environments)
+
+       Version 1.5 - 2005-01-01
+       - 64-bit compiler compatibility added
+       - Made variable wiping optional (define SHA1_WIPE_VARIABLES)
+       - Removed unnecessary variable initializations
+       - ROL32 improvement for the Microsoft compiler (using _rotl)
+
+       ======== Test Vectors (from FIPS PUB 180-1) ========
+
+       SHA1("abc") =
+               A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+
+       SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
+               84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+
+       SHA1(A million repetitions of "a") =
+               34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+#include "SHA1.h"
+
+#ifdef SHA1_UTILITY_FUNCTIONS
+#define SHA1_MAX_FILE_BUFFER 8000
+#endif
+
+// Rotate x bits to the left
+#ifndef ROL32
+#ifdef _MSC_VER
+#define ROL32(_val32, _nBits) _rotl(_val32, _nBits)
+#else
+#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits))))
+#endif
+#endif
+
+#ifdef SHA1_LITTLE_ENDIAN
+#define SHABLK0(i) (m_block->l[i] = \
+       (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF))
+#else
+#define SHABLK0(i) (m_block->l[i])
+#endif
+
+#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \
+       ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1))
+
+// SHA-1 rounds
+#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
+#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
+#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); }
+#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); }
+#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); }
+
+CSHA1::CSHA1()
+{
+       m_block = (SHA1_WORKSPACE_BLOCK *)m_workspace;
+
+       Reset();
+}
+
+CSHA1::~CSHA1()
+{
+       Reset();
+}
+
+void CSHA1::Reset()
+{
+       // SHA1 initialization constants
+       m_state[0] = 0x67452301;
+       m_state[1] = 0xEFCDAB89;
+       m_state[2] = 0x98BADCFE;
+       m_state[3] = 0x10325476;
+       m_state[4] = 0xC3D2E1F0;
+
+       m_count[0] = 0;
+       m_count[1] = 0;
+}
+
+void CSHA1::Transform(uint32_t *state, const uint8_t *buffer)
+{
+       // Copy state[] to working vars
+       uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
+
+       memcpy(m_block, buffer, 64);
+
+       // 4 rounds of 20 operations each. Loop unrolled.
+       _R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3);
+       _R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7);
+       _R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11);
+       _R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15);
+       _R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19);
+       _R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23);
+       _R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27);
+       _R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31);
+       _R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35);
+       _R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39);
+       _R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43);
+       _R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47);
+       _R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51);
+       _R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55);
+       _R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59);
+       _R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63);
+       _R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67);
+       _R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71);
+       _R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75);
+       _R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79);
+
+       // Add the working vars back into state
+       state[0] += a;
+       state[1] += b;
+       state[2] += c;
+       state[3] += d;
+       state[4] += e;
+
+       // Wipe variables
+#ifdef SHA1_WIPE_VARIABLES
+       a = b = c = d = e = 0;
+#endif
+}
+
+// Use this function to hash in binary data and strings
+void CSHA1::Update(const uint8_t *data, uint32_t len)
+{
+       uint32_t i, j;
+
+       j = (m_count[0] >> 3) & 63;
+
+       if((m_count[0] += len << 3) < (len << 3)) m_count[1]++;
+
+       m_count[1] += (len >> 29);
+
+       if((j + len) > 63)
+       {
+               i = 64 - j;
+               memcpy(&m_buffer[j], data, i);
+               Transform(m_state, m_buffer);
+
+               for( ; i + 63 < len; i += 64) Transform(m_state, &data[i]);
+
+               j = 0;
+       }
+       else i = 0;
+
+       memcpy(&m_buffer[j], &data[i], len - i);
+}
+
+#ifdef SHA1_UTILITY_FUNCTIONS
+// Hash in file contents
+bool CSHA1::HashFile(char *szFileName)
+{
+       unsigned long ulFileSize, ulRest, ulBlocks;
+       unsigned long i;
+       uint8_t uData[SHA1_MAX_FILE_BUFFER];
+       FILE *fIn;
+
+       if(szFileName == NULL) return false;
+
+       fIn = fopen(szFileName, "rb");
+       if(fIn == NULL) return false;
+
+       fseek(fIn, 0, SEEK_END);
+       ulFileSize = (unsigned long)ftell(fIn);
+       fseek(fIn, 0, SEEK_SET);
+
+       if(ulFileSize != 0)
+       {
+               ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER;
+               ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER;
+       }
+       else
+       {
+               ulBlocks = 0;
+               ulRest = 0;
+       }
+
+       for(i = 0; i < ulBlocks; i++)
+       {
+               fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn);
+               Update((uint8_t *)uData, SHA1_MAX_FILE_BUFFER);
+       }
+
+       if(ulRest != 0)
+       {
+               fread(uData, 1, ulRest, fIn);
+               Update((uint8_t *)uData, ulRest);
+       }
+
+       fclose(fIn); fIn = NULL;
+       return true;
+}
+#endif
+
+void CSHA1::Final()
+{
+       uint32_t i;
+       uint8_t finalcount[8];
+
+       for(i = 0; i < 8; i++)
+               finalcount[i] = (uint8_t)((m_count[((i >= 4) ? 0 : 1)]
+                       >> ((3 - (i & 3)) * 8) ) & 255); // Endian independent
+
+       Update((uint8_t *)"\200", 1);
+
+       while ((m_count[0] & 504) != 448)
+               Update((uint8_t *)"\0", 1);
+
+       Update(finalcount, 8); // Cause a SHA1Transform()
+
+       for(i = 0; i < 20; i++)
+       {
+               m_digest[i] = (uint8_t)((m_state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255);
+       }
+
+       // Wipe variables for security reasons
+#ifdef SHA1_WIPE_VARIABLES
+       i = 0;
+       memset(m_buffer, 0, 64);
+       memset(m_state, 0, 20);
+       memset(m_count, 0, 8);
+       memset(finalcount, 0, 8);
+       Transform(m_state, m_buffer);
+#endif
+}
+
+#ifdef SHA1_UTILITY_FUNCTIONS
+// Get the final hash as a pre-formatted string
+void CSHA1::ReportHash(char *szReport, unsigned char uReportType)
+{
+       unsigned char i;
+       char szTemp[16];
+
+       if(szReport == NULL) return;
+
+       if(uReportType == REPORT_HEX)
+       {
+               sprintf(szTemp, "%02X", m_digest[0]);
+               strcat(szReport, szTemp);
+
+               for(i = 1; i < 20; i++)
+               {
+                       sprintf(szTemp, " %02X", m_digest[i]);
+                       strcat(szReport, szTemp);
+               }
+       }
+       else if(uReportType == REPORT_DIGIT)
+       {
+               sprintf(szTemp, "%u", m_digest[0]);
+               strcat(szReport, szTemp);
+
+               for(i = 1; i < 20; i++)
+               {
+                       sprintf(szTemp, " %u", m_digest[i]);
+                       strcat(szReport, szTemp);
+               }
+       }
+       else strcpy(szReport, "Error: Unknown report type!");
+}
+#endif
+
+// Get the raw message digest
+void CSHA1::GetHash(uint8_t *puDest)
+{
+       memcpy(puDest, m_digest, 20);
+}
diff --git a/tools/elftosb/common/SHA1.h b/tools/elftosb/common/SHA1.h
new file mode 100644 (file)
index 0000000..114ece4
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+       100% free public domain implementation of the SHA-1 algorithm
+       by Dominik Reichl <dominik.reichl@t-online.de>
+       Web: http://www.dominik-reichl.de/
+
+       Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
+       - You can set the endianness in your files, no need to modify the
+         header file of the CSHA1 class any more
+       - Aligned data support
+       - Made support/compilation of the utility functions (ReportHash
+         and HashFile) optional (useful, if bytes count, for example in
+         embedded environments)
+
+       Version 1.5 - 2005-01-01
+       - 64-bit compiler compatibility added
+       - Made variable wiping optional (define SHA1_WIPE_VARIABLES)
+       - Removed unnecessary variable initializations
+       - ROL32 improvement for the Microsoft compiler (using _rotl)
+
+       ======== Test Vectors (from FIPS PUB 180-1) ========
+
+       SHA1("abc") =
+               A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+
+       SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
+               84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+
+       SHA1(A million repetitions of "a") =
+               34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+#ifndef ___SHA1_HDR___
+#define ___SHA1_HDR___
+
+#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)
+#define SHA1_UTILITY_FUNCTIONS
+#endif
+
+#include <memory.h> // Needed for memset and memcpy
+#include "stdafx.h"
+
+#ifdef SHA1_UTILITY_FUNCTIONS
+#include <stdio.h>  // Needed for file access and sprintf
+#include <string.h> // Needed for strcat and strcpy
+#endif
+
+#ifdef _MSC_VER
+#include <stdlib.h>
+#endif
+
+// You can define the endian mode in your files, without modifying the SHA1
+// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN
+// in your files, before including the SHA1.h header file. If you don't
+// define anything, the class defaults to little endian.
+
+#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
+#define SHA1_LITTLE_ENDIAN
+#endif
+
+// Same here. If you want variable wiping, #define SHA1_WIPE_VARIABLES, if
+// not, #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it
+// defaults to wiping.
+
+#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES)
+#define SHA1_WIPE_VARIABLES
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Define 8- and 32-bit variables
+
+//#ifndef uint32_t
+//
+//#ifdef _MSC_VER
+//
+//#define uint8_t  unsigned __int8
+//#define uint32_t unsigned __int32
+//
+//#else
+//
+//#define uint8_t unsigned char
+//
+//#if (ULONG_MAX == 0xFFFFFFFF)
+//#define uint32_t unsigned long
+//#else
+//#define uint32_t unsigned int
+//#endif
+//
+//#endif
+//#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Declare SHA1 workspace
+
+typedef union
+{
+       uint8_t  c[64];
+       uint32_t l[16];
+} SHA1_WORKSPACE_BLOCK;
+
+class CSHA1
+{
+public:
+#ifdef SHA1_UTILITY_FUNCTIONS
+       // Two different formats for ReportHash(...)
+       enum
+       {
+               REPORT_HEX = 0,
+               REPORT_DIGIT = 1
+       };
+#endif
+
+       // Constructor and Destructor
+       CSHA1();
+       ~CSHA1();
+
+       uint32_t m_state[5];
+       uint32_t m_count[2];
+       uint32_t __reserved1[1];
+       uint8_t  m_buffer[64];
+       uint8_t  m_digest[20];
+       uint32_t __reserved2[3];
+
+       void Reset();
+
+       // Update the hash value
+       void Update(const uint8_t *data, uint32_t len);
+#ifdef SHA1_UTILITY_FUNCTIONS
+       bool HashFile(char *szFileName);
+#endif
+
+       // Finalize hash and report
+       void Final();
+
+       // Report functions: as pre-formatted and raw data
+#ifdef SHA1_UTILITY_FUNCTIONS
+       void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX);
+#endif
+       void GetHash(uint8_t *puDest);
+
+private:
+       // Private SHA-1 transformation
+       void Transform(uint32_t *state, const uint8_t *buffer);
+
+       // Member variables
+       uint8_t m_workspace[64];
+       SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above
+};
+
+#endif
diff --git a/tools/elftosb/common/SRecordSourceFile.cpp b/tools/elftosb/common/SRecordSourceFile.cpp
new file mode 100644 (file)
index 0000000..3521c69
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * File:       SRecordSourceFile.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "SRecordSourceFile.h"
+#include "Logging.h"
+#include "smart_ptr.h"
+#include <assert.h>
+#include <string.h>
+enum
+{
+       //! Size in bytes of the buffer used to collect S-record data records
+       //! before adding them to the executable image. Currently 64KB.
+       COLLECTION_BUFFER_SIZE = 64 * 1024
+};
+
+using namespace elftosb;
+
+SRecordSourceFile::SRecordSourceFile(const std::string & path)
+:      SourceFile(path), m_image(0), m_hasEntryRecord(false)
+{
+}
+
+bool SRecordSourceFile::isSRecordFile(std::istream & stream)
+{
+       StSRecordFile srec(stream);
+       return srec.isSRecordFile();
+}
+
+void SRecordSourceFile::open()
+{
+       SourceFile::open();
+       
+       // create file parser and examine file
+       m_file = new StSRecordFile(*m_stream);
+       m_file->parse();
+       
+       // build an image of the file
+       m_image = new StExecutableImage();
+       buildMemoryImage();
+       
+       // dispose of file parser object
+       delete m_file;
+       m_file = 0;
+}
+
+void SRecordSourceFile::close()
+{
+       assert(m_image);
+       
+       SourceFile::close();
+       
+       // dispose of memory image
+       delete m_image;
+       m_image = 0;
+}
+
+//! \pre The file must be open before this method can be called.
+//!
+DataSource * SRecordSourceFile::createDataSource()
+{
+       assert(m_image);
+       return new MemoryImageDataSource(m_image);
+}
+
+//! \retval true The file has an S7, S8, or S9 record.
+//! \retval false No entry point is available.
+bool SRecordSourceFile::hasEntryPoint()
+{
+       return m_hasEntryRecord;
+}
+
+//! If no entry point is available then 0 is returned instead. The method scans
+//! the records in the file looking for S7, S8, or S9 records. Thus, 16-bit,
+//! 24-bit, and 32-bit entry point records are supported.
+//!
+//! \return Entry point address.
+//! \retval 0 No entry point is available.
+uint32_t SRecordSourceFile::getEntryPointAddress()
+{
+       if (m_hasEntryRecord)
+       {
+               // the address in the record is the entry point
+               Log::log(Logger::DEBUG2, "entry point address is 0x%08x\n", m_entryRecord.m_address);
+               return m_entryRecord.m_address;
+       }
+       
+       return 0;
+}
+
+//! Scans the S-records of the file looking for data records. These are S3, S2, or
+//! S1 records. The contents of these records are added to an StExecutableImage
+//! object, which coalesces the individual records into contiguous regions of
+//! memory.
+//!
+//! Also looks for S7, S8, or S9 records that contain the entry point. The first
+//! match of one of these records is saved off into the #m_entryRecord member.
+//! 
+//! \pre The #m_file member must be valid.
+//! \pre The #m_image member variable must have been instantiated.
+void SRecordSourceFile::buildMemoryImage()
+{
+       assert(m_file);
+       assert(m_image);
+       
+       // Clear the entry point related members.
+       m_hasEntryRecord = false;
+       memset(&m_entryRecord, 0, sizeof(m_entryRecord));
+       
+       // Allocate buffer to hold data before adding it to the executable image.
+       // Contiguous records are added to this buffer. When overflowed or when a
+       // non-contiguous record is encountered the buffer is added to the executable
+       // image where it will be coalesced further. We don't add records individually
+       // to the image because coalescing record by record is very slow.
+       smart_array_ptr<uint8_t> buffer = new uint8_t[COLLECTION_BUFFER_SIZE];
+       unsigned startAddress;
+       unsigned nextAddress;
+       unsigned dataLength = 0;
+       
+       // process SRecords
+    StSRecordFile::const_iterator it = m_file->getBegin();
+       for (; it != m_file->getEnd(); it++)
+       {
+        const StSRecordFile::SRecord & theRecord = *it;
+        
+        // only handle S3,2,1 records
+        bool isDataRecord = theRecord.m_type == 3 || theRecord.m_type == 2 || theRecord.m_type == 1;
+        bool hasData = theRecord.m_data && theRecord.m_dataCount;
+               if (isDataRecord && hasData)
+               {
+                       // If this record's data would overflow the collection buffer, or if the
+                       // record is not contiguous with the rest of the data in the collection
+                       // buffer, then flush the buffer to the executable image and restart.
+                       if (dataLength && ((dataLength + theRecord.m_dataCount > COLLECTION_BUFFER_SIZE) || (theRecord.m_address != nextAddress)))
+                       {
+                               m_image->addTextRegion(startAddress, buffer, dataLength);
+                               
+                               dataLength = 0;
+                       }
+                       
+                       // Capture addresses when starting an empty buffer.
+                       if (dataLength == 0)
+                       {
+                               startAddress = theRecord.m_address;
+                               nextAddress = startAddress;
+                       }
+                       
+                       // Copy record data into place in the collection buffer and update
+                       // size and address.
+                       memcpy(&buffer[dataLength], theRecord.m_data, theRecord.m_dataCount);
+                       dataLength += theRecord.m_dataCount;
+                       nextAddress += theRecord.m_dataCount;
+               }
+               else if (!m_hasEntryRecord)
+               {
+                       // look for S7,8,9 records
+                       bool isEntryPointRecord = theRecord.m_type == 7 || theRecord.m_type == 8 || theRecord.m_type == 9;
+                       if (isEntryPointRecord)
+                       {
+                               // save off the entry point record so we don't have to scan again
+                               memcpy(&m_entryRecord, &theRecord, sizeof(m_entryRecord));
+                               m_hasEntryRecord = true;
+                       }
+               }
+       }
+       
+       // Add any leftover data in the collection buffer to the executable image.
+       if (dataLength)
+       {
+               m_image->addTextRegion(startAddress, buffer, dataLength);
+       }
+}
+
diff --git a/tools/elftosb/common/SRecordSourceFile.h b/tools/elftosb/common/SRecordSourceFile.h
new file mode 100644 (file)
index 0000000..c0bc2a9
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * File:       SRecordSourceFile.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_SRecordSourceFile_h_)
+#define _SRecordSourceFile_h_
+
+#include "SourceFile.h"
+#include "StSRecordFile.h"
+#include "StExecutableImage.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Executable file in the Motorola S-record format.
+ *
+ * Instead of presenting each S-record in the file separately, this class
+ * builds up a memory image of all of the records. Records next to each other
+ * in memory are coalesced into a single memory region. The data source that
+ * is returned from createDataSource() exposes these regions as its segments.
+ *
+ * Because the S-record format does not support the concepts, no support is
+ * provided for named sections or symbols.
+ */
+class SRecordSourceFile : public SourceFile
+{
+public:
+       //! \brief Default constructor.
+       SRecordSourceFile(const std::string & path);
+       
+       //! \brief Destructor.
+       virtual ~SRecordSourceFile() {}
+       
+       //! \brief Test whether the \a stream contains a valid S-record file.
+       static bool isSRecordFile(std::istream & stream);
+       
+       //! \name Opening and closing
+       //@{
+       //! \brief Opens the file.
+       virtual void open();
+       
+       //! \brief Closes the file.
+       virtual void close();
+       //@}
+       
+       //! \name Format capabilities
+       //@{
+       virtual bool supportsNamedSections() const { return false; }
+       virtual bool supportsNamedSymbols() const { return false; }
+       //@}
+       
+       //! \name Data sources
+       //@{
+       //! \brief Returns data source for the entire file.
+       virtual DataSource * createDataSource();
+       //@}
+       
+       //! \name Entry point
+       //@{
+       //! \brief Returns true if an entry point was set in the file.
+       virtual bool hasEntryPoint();
+       
+       //! \brief Returns the entry point address.
+       virtual uint32_t getEntryPointAddress();
+       //@}
+
+protected:
+       StSRecordFile * m_file; //!< S-record parser instance.
+       StExecutableImage * m_image;    //!< Memory image of the S-record file.
+       bool m_hasEntryRecord;  //!< Whether an S7,8,9 record was found.
+       StSRecordFile::SRecord m_entryRecord;   //!< Record for the entry point.
+       
+protected:
+       //! \brief Build memory image of the S-record file.
+       void buildMemoryImage();
+};
+
+}; // namespace elftosb
+
+#endif // _SRecordSourceFile_h_
diff --git a/tools/elftosb/common/SearchPath.cpp b/tools/elftosb/common/SearchPath.cpp
new file mode 100644 (file)
index 0000000..8a8a742
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * File:       SearchPath.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "SearchPath.h"
+#include <stdio.h>
+
+#if defined(WIN32)
+       #define PATH_SEP_CHAR '\\'
+       #define PATH_SEP_STRING "\\"
+#else
+       #define PATH_SEP_CHAR '/'
+       #define PATH_SEP_STRING "/"
+#endif
+
+PathSearcher * PathSearcher::s_searcher = NULL;
+
+//! This function will create the global path search object if it has
+//! not already been created.
+PathSearcher & PathSearcher::getGlobalSearcher()
+{
+       if (!s_searcher)
+       {
+               s_searcher = new PathSearcher;
+       }
+       
+       return *s_searcher;
+}
+
+void PathSearcher::addSearchPath(std::string & path)
+{
+       m_paths.push_back(path);
+}
+
+//! The \a base path argument can be either a relative or absolute path. If the path
+//! is relative, then it is joined with search paths one after another until a matching
+//! file is located or all search paths are exhausted. If the \a base is absolute,
+//! only that path is tested and if invalid false is returned.
+//!
+//! \param base A path to the file that is to be found.
+//! \param targetType Currently ignored. In the future it will let you select whether to
+//!            find a file or directory.
+//! \param searchCwd If set to true, the current working directory is searched before using
+//!            any of the search paths. Otherwise only the search paths are considered.
+//! \param[out] result When true is returned this string is set to the first path at which
+//!            a valid file was found.
+//!
+//! \retval true A matching file was found among the search paths. The contents of \a result
+//!            are a valid path.
+//! \retval false No match could be made. \a result has been left unmodified.
+bool PathSearcher::search(const std::string & base, target_type_t targetType, bool searchCwd, std::string & result)
+{
+       FILE * tempFile;
+       bool absolute = isAbsolute(base);
+       
+       // Try cwd first if requested. Same process applies to absolute paths.
+       if (absolute || searchCwd)
+       {
+               tempFile = fopen(base.c_str(), "r");
+               if (tempFile)
+               {
+                       fclose(tempFile);
+                       result = base;
+                       return true;
+               }
+       }
+       
+       // If the base path is absolute and the previous test failed, then we don't go any further.
+       if (absolute)
+       {
+               return false;
+       }
+       
+       // Iterate over all search paths.
+       string_list_t::const_iterator it = m_paths.begin();
+       for (; it != m_paths.end(); ++it)
+       {
+               std::string searchPath = joinPaths(*it, base);
+               
+               tempFile = fopen(searchPath.c_str(), "r");
+               if (tempFile)
+               {
+                       fclose(tempFile);
+                       result = searchPath;
+                       return true;
+               }
+       }
+       
+       // Couldn't find anything matching the base path.
+       return false;
+}
+
+bool PathSearcher::isAbsolute(const std::string & path)
+{
+#if __WIN32__
+       return path.size() >= 3 && path[1] == ':' && path[2] == '\\';
+#else
+       return path.size() >= 1 && path[0] == '/';
+#endif
+}
+
+std::string PathSearcher::joinPaths(const std::string & first, const std::string & second)
+{
+       // Start with first string.
+       std::string result = first;
+       
+       // Add path separator if needed
+       if ((first[first.size() - 1] != PATH_SEP_CHAR) && (second[0] != PATH_SEP_CHAR))
+       {
+               result += PATH_SEP_STRING;
+       }
+       
+       // Append the second string.
+       result += second;
+       
+       // And return the whole mess.
+       return result;
+}
diff --git a/tools/elftosb/common/SearchPath.h b/tools/elftosb/common/SearchPath.h
new file mode 100644 (file)
index 0000000..4ae6018
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * File:       SearchPath.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_searchpath_h_)
+#define _searchpath_h_
+
+#include <string>
+#include <list>
+
+/*!
+ * \brief Handles searching a list of paths for a file.
+ */
+class PathSearcher
+{
+public:
+       //!
+       enum _target_type
+       {
+               kFindFile,
+               kFindDirectory
+       };
+       
+       //!
+       typedef enum _target_type target_type_t;
+       
+protected:
+       //! Global search object singleton.
+       static PathSearcher * s_searcher;
+       
+public:
+       //! \brief Access global path searching object.
+       static PathSearcher & getGlobalSearcher();
+       
+public:
+       //! \brief Constructor.
+       PathSearcher() {}
+       
+       //! \brief Add a new search path to the end of the list.
+       void addSearchPath(std::string & path);
+       
+       //! \brief Attempts to locate a file by using the search paths.
+       bool search(const std::string & base, target_type_t targetType, bool searchCwd, std::string & result);
+
+protected:
+       typedef std::list<std::string> string_list_t;   //!< Linked list of strings.
+       string_list_t m_paths;  //!< Ordered list of paths to search.
+       
+       //! \brief Returns whether \a path is absolute.
+       bool isAbsolute(const std::string & path);
+       
+       //! \brief Combines two paths into a single one.
+       std::string joinPaths(const std::string & first, const std::string & second);
+};
+
+#endif // _searchpath_h_
diff --git a/tools/elftosb/common/SourceFile.cpp b/tools/elftosb/common/SourceFile.cpp
new file mode 100644 (file)
index 0000000..947ae17
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * File:       SourceFile.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "SourceFile.h"
+#include "ELFSourceFile.h"
+#include "SRecordSourceFile.h"
+#include <assert.h>
+#include "format_string.h"
+#include "SearchPath.h"
+
+using namespace elftosb;
+
+//! The supported file types are currently:
+//!            - ELF files
+//!            - Motorola S-record files
+//!            - Binary files
+//!
+//! Any file that is not picked up by the other subclasses will result in a
+//! an instance of BinaryDataFile.
+//!
+//! \return An instance of the correct subclass of SourceFile for the given path.
+//!
+//! \exception std::runtime_error Thrown if the file cannot be opened.
+//!
+//! \see elftosb::ELFSourceFile
+//! \see elftosb::SRecordSourceFile
+//! \see elftosb::BinarySourceFile
+SourceFile * SourceFile::openFile(const std::string & path)
+{
+       // Search for file using search paths
+       std::string actualPath;
+       bool found = PathSearcher::getGlobalSearcher().search(path, PathSearcher::kFindFile, true, actualPath);
+       if (!found)
+       {
+               throw std::runtime_error(format_string("unable to find file %s\n", path.c_str()));
+       }
+
+       std::ifstream testStream(actualPath.c_str(), std::ios_base::in | std::ios_base::binary);
+       if (!testStream.is_open())
+       {
+               throw std::runtime_error(format_string("failed to open file: %s", actualPath.c_str()));
+       }
+       
+       // catch exceptions so we can close the file stream
+       try
+       {
+               if (ELFSourceFile::isELFFile(testStream))
+               {
+                       testStream.close();
+                       return new ELFSourceFile(actualPath);
+               }
+               else if (SRecordSourceFile::isSRecordFile(testStream))
+               {
+                       testStream.close();
+                       return new SRecordSourceFile(actualPath);
+               }
+               
+               // treat it as a binary file
+               testStream.close();
+               return new BinarySourceFile(actualPath);
+       }
+       catch (...)
+       {
+               testStream.close();
+               throw;
+       }
+}
+
+SourceFile::SourceFile(const std::string & path)
+:      m_path(path), m_stream()
+{
+}
+
+//! The file is closed if it had been left opened.
+//!
+SourceFile::~SourceFile()
+{
+       if (isOpen())
+       {
+               m_stream->close();
+       }
+}
+
+//! \exception std::runtime_error Raised if the file could not be opened successfully.
+void SourceFile::open()
+{
+       assert(!isOpen());
+       m_stream = new std::ifstream(m_path.c_str(), std::ios_base::in | std::ios_base::binary);
+       if (!m_stream->is_open())
+       {
+               throw std::runtime_error(format_string("failed to open file: %s", m_path.c_str()));
+       }
+}
+
+void SourceFile::close()
+{
+       assert(isOpen());
+       
+       m_stream->close();
+       m_stream.safe_delete();
+}
+
+unsigned SourceFile::getSize()
+{
+       bool wasOpen = isOpen();
+       std::ifstream::pos_type oldPosition;
+       
+       if (!wasOpen)
+       {
+               open();
+       }
+       
+       assert(m_stream);
+       oldPosition = m_stream->tellg();
+       m_stream->seekg(0, std::ios_base::end);
+       unsigned resultSize = m_stream->tellg();
+       m_stream->seekg(oldPosition);
+       
+       if (!wasOpen)
+       {
+               close();
+       }
+       
+       return resultSize;
+}
+
+//! If the file does not support named sections, or if there is not a
+//! section with the given name, this method may return NULL.
+//!
+//! This method is just a small wrapper that creates an
+//! FixedMatcher string matcher instance and uses the createDataSource()
+//! that takes a reference to a StringMatcher.
+DataSource * SourceFile::createDataSource(const std::string & section)
+{
+       FixedMatcher matcher(section);
+       return createDataSource(matcher);
+}
+
+DataTarget * SourceFile::createDataTargetForEntryPoint()
+{
+       if (!hasEntryPoint())
+       {
+               return NULL;
+       }
+       
+       return new ConstantDataTarget(getEntryPointAddress());
+}
+
+DataSource * BinarySourceFile::createDataSource()
+{
+       std::istream * fileStream = getStream();
+       assert(fileStream);
+       
+       // get stream size
+       fileStream->seekg(0, std::ios_base::end);
+       int length = fileStream->tellg();
+       
+       // allocate buffer
+       smart_array_ptr<uint8_t> data = new uint8_t[length];
+//     if (!data)
+//     {
+//         throw std::bad_alloc();
+//     }
+       
+       // read entire file into the buffer
+       fileStream->seekg(0, std::ios_base::beg);
+       if (fileStream->read((char *)data.get(), length).bad())
+       {
+               throw std::runtime_error(format_string("unexpected end of file: %s", m_path.c_str()));
+       }
+       
+       // create the data source. the buffer is copied, so we can dispose of it.
+       return new UnmappedDataSource(data, length);
+}
diff --git a/tools/elftosb/common/SourceFile.h b/tools/elftosb/common/SourceFile.h
new file mode 100644 (file)
index 0000000..773dd5b
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * File:       SourceFile.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_SourceFile_h_)
+#define _SourceFile_h_
+
+#include <string>
+#include <iostream>
+#include <fstream>
+#include "smart_ptr.h"
+#include "DataSource.h"
+#include "DataTarget.h"
+#include "StringMatcher.h"
+#include "OptionContext.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Abstract base class for a source file containing executable code.
+ *
+ * The purpose of this class cluster is to provide a common interface for
+ * accessing the contents of different file formats. This is accomplished
+ * through several small sets of methods along with the DataSource and
+ * DataTarget classes.
+ *
+ * The primary interface for creating instances of SourceFile is the static
+ * SourceFile::openFile() function. It will create the correct subclass of
+ * SourceFile by inspecting the file to determine its type.
+ */
+class SourceFile
+{
+public:
+       // \brief Factory function that creates the correct subclass of SourceFile.
+       static SourceFile * openFile(const std::string & path);
+       
+public:
+       //! \brief Default constructor.
+       SourceFile(const std::string & path);
+       
+       //! \brief Destructor.
+       virtual ~SourceFile();
+       
+       //! \brief Set the option context.
+       //!
+       //! The source file will take ownership of the @a context and delete it
+       //! when the source file is itself deleted.
+       inline void setOptions(OptionContext * context) { m_options = context; }
+       
+       //! \brief Return the option context.
+       inline const OptionContext * getOptions() const { return m_options; }
+       
+       //! \brief Returns the path to the file.
+       inline const std::string & getPath() const { return m_path; }
+       
+       //! \brief Get the size in bytes of the file.
+       unsigned getSize();
+       
+       //! \name Opening and closing
+       //@{
+       //! \brief Opens the file.
+       virtual void open();
+       
+       //! \brief Closes the file.
+       virtual void close();
+       
+       //! \brief Returns whether the file is already open.
+       virtual bool isOpen() const { return (bool)m_stream && const_cast<std::ifstream*>(m_stream.get())->is_open(); }
+       //@}
+       
+       //! \name Format capabilities
+       //@{
+       virtual bool supportsNamedSections() const=0;
+       virtual bool supportsNamedSymbols() const=0;
+       //@}
+       
+       //! \name Data source creation
+       //@{
+       //! \brief Creates a data source from the entire file.
+       virtual DataSource * createDataSource()=0;
+       
+       //! \brief Creates a data source out of one or more sections of the file.
+       //!
+       //! The \a selector object is used to perform the section name comparison.
+       //! If the file does not support named sections, or if there is not a
+       //! section with the given name, this method may return NULL.
+       virtual DataSource * createDataSource(StringMatcher & matcher) { return NULL; }
+       
+       //! \brief Creates a data source out of one section of the file.
+       virtual DataSource * createDataSource(const std::string & section);
+       //@}
+       
+       //! \name Entry point
+       //@{
+       //! \brief Returns true if an entry point was set in the file.
+       virtual bool hasEntryPoint()=0;
+       
+       //! \brief Returns the entry point address.
+       virtual uint32_t getEntryPointAddress() { return 0; }
+       //@}
+       
+       //! \name Data target creation
+       //@{
+       virtual DataTarget * createDataTargetForSection(const std::string & section) { return NULL; }
+       virtual DataTarget * createDataTargetForSymbol(const std::string & symbol) { return NULL; }
+       virtual DataTarget * createDataTargetForEntryPoint();
+       //@}
+       
+       //! \name Symbols
+       //@{
+       //! \brief Returns whether a symbol exists in the source file.
+       virtual bool hasSymbol(const std::string & name) { return false; }
+       
+       //! \brief Returns the value of a symbol.
+       virtual uint32_t getSymbolValue(const std::string & name) { return 0; }
+       
+       //! \brief Returns the size of a symbol.
+       virtual unsigned getSymbolSize(const std::string & name) { return 0; }
+       //@}
+       
+protected:
+       std::string m_path;     //!< Path to the file.
+       smart_ptr<std::ifstream> m_stream;      //!< File stream, or NULL if file is closed.
+       smart_ptr<OptionContext> m_options;     //!< Table of option values.
+       
+       //! \brief Internal access to the input stream object.
+       inline std::ifstream * getStream() { return m_stream; }
+};
+
+/*!
+ * \brief Binary data file.
+ */
+class BinarySourceFile : public SourceFile
+{
+public:
+       //! \brief Default constructor.
+       BinarySourceFile(const std::string & path) : SourceFile(path) {}
+       
+       //! \name Format capabilities
+       //@{
+       virtual bool supportsNamedSections() const { return false; }
+       virtual bool supportsNamedSymbols() const { return false; }
+       //@}
+       
+       //! \brief Creates an unmapped data source from the entire file.
+       virtual DataSource * createDataSource();
+       
+       virtual bool hasEntryPoint() { return false; }
+};
+
+}; // namespace elftosb
+
+#endif // _SourceFile_h_
diff --git a/tools/elftosb/common/StELFFile.cpp b/tools/elftosb/common/StELFFile.cpp
new file mode 100644 (file)
index 0000000..09124d5
--- /dev/null
@@ -0,0 +1,543 @@
+/*
+ * File:       StELFFile.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "StELFFile.h"
+#include <ios>
+#include <stdexcept>
+#include <stdio.h>
+#include "EndianUtilities.h"
+
+//! \exception StELFFileException is thrown if there is a problem with the file format.
+//!
+StELFFile::StELFFile(std::istream & inStream)
+:      m_stream(inStream)
+{
+       readFileHeaders();
+}
+
+//! Disposes of the string table data.
+StELFFile::~StELFFile()
+{
+       SectionDataMap::iterator it = m_sectionDataCache.begin();
+       for (; it != m_sectionDataCache.end(); ++it)
+       {
+               SectionDataInfo & info = it->second;
+               if (info.m_data != NULL)
+               {
+                       delete [] info.m_data;
+               }
+       }
+}
+
+//! \exception StELFFileException is thrown if the file is not an ELF file.
+//!
+void StELFFile::readFileHeaders()
+{
+       // move read head to beginning of stream
+       m_stream.seekg(0, std::ios_base::beg);
+       
+       // read ELF header
+       m_stream.read(reinterpret_cast<char *>(&m_header), sizeof(m_header));
+       if (m_stream.bad())
+       {
+               throw StELFFileException("could not read file header");
+       }
+       
+       // convert endianness
+       m_header.e_type = ENDIAN_LITTLE_TO_HOST_U16(m_header.e_type);
+       m_header.e_machine = ENDIAN_LITTLE_TO_HOST_U16(m_header.e_machine);
+       m_header.e_version = ENDIAN_LITTLE_TO_HOST_U32(m_header.e_version);
+       m_header.e_entry = ENDIAN_LITTLE_TO_HOST_U32(m_header.e_entry);
+       m_header.e_phoff = ENDIAN_LITTLE_TO_HOST_U32(m_header.e_phoff);
+       m_header.e_shoff = ENDIAN_LITTLE_TO_HOST_U32(m_header.e_shoff);
+       m_header.e_flags = ENDIAN_LITTLE_TO_HOST_U32(m_header.e_flags);
+       m_header.e_ehsize = ENDIAN_LITTLE_TO_HOST_U16(m_header.e_ehsize);
+       m_header.e_phentsize = ENDIAN_LITTLE_TO_HOST_U16(m_header.e_phentsize);
+       m_header.e_phnum = ENDIAN_LITTLE_TO_HOST_U16(m_header.e_phnum);
+       m_header.e_shentsize = ENDIAN_LITTLE_TO_HOST_U16(m_header.e_shentsize);
+       m_header.e_shnum = ENDIAN_LITTLE_TO_HOST_U16(m_header.e_shnum);
+       m_header.e_shstrndx = ENDIAN_LITTLE_TO_HOST_U16(m_header.e_shstrndx);
+       
+       // check magic number
+       if (!(m_header.e_ident[EI_MAG0] == ELFMAG0 && m_header.e_ident[EI_MAG1] == ELFMAG1 && m_header.e_ident[EI_MAG2] == ELFMAG2 && m_header.e_ident[EI_MAG3] == ELFMAG3))
+       {
+               throw StELFFileException("invalid magic number in ELF header");
+       }
+       
+       try
+       {
+               int i;
+               
+               // read section headers
+               if (m_header.e_shoff != 0 && m_header.e_shnum > 0)
+               {
+                       Elf32_Shdr sectionHeader;
+                       for (i=0; i < m_header.e_shnum; ++i)
+                       {
+                               m_stream.seekg(m_header.e_shoff + m_header.e_shentsize * i, std::ios::beg);
+                               m_stream.read(reinterpret_cast<char *>(&sectionHeader), sizeof(sectionHeader));
+                               if (m_stream.bad())
+                               {
+                                       throw StELFFileException("could not read section header");
+                               }
+                               
+                               // convert endianness
+                               sectionHeader.sh_name = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_name);
+                               sectionHeader.sh_type = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_type);
+                               sectionHeader.sh_flags = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_flags);
+                               sectionHeader.sh_addr = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_addr);
+                               sectionHeader.sh_offset = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_offset);
+                               sectionHeader.sh_size = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_size);
+                               sectionHeader.sh_link = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_link);
+                               sectionHeader.sh_info = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_info);
+                               sectionHeader.sh_addralign = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_addralign);
+                               sectionHeader.sh_entsize = ENDIAN_LITTLE_TO_HOST_U32(sectionHeader.sh_entsize);
+                               
+                               m_sectionHeaders.push_back(sectionHeader);
+                       }
+               }
+               
+               // read program headers
+               if (m_header.e_phoff != 0 && m_header.e_phnum > 0)
+               {
+                       Elf32_Phdr programHeader;
+                       for (i=0; i < m_header.e_phnum; ++i)
+                       {
+                               m_stream.seekg(m_header.e_phoff + m_header.e_phentsize * i, std::ios::beg);
+                               m_stream.read(reinterpret_cast<char *>(&programHeader), sizeof(programHeader));
+                               if (m_stream.bad())
+                               {
+                                       throw StELFFileException("could not read program header");
+                               }
+                               
+                               // convert endianness
+                               programHeader.p_type = ENDIAN_LITTLE_TO_HOST_U32(programHeader.p_type);
+                               programHeader.p_offset = ENDIAN_LITTLE_TO_HOST_U32(programHeader.p_type);
+                               programHeader.p_vaddr = ENDIAN_LITTLE_TO_HOST_U32(programHeader.p_vaddr);
+                               programHeader.p_paddr = ENDIAN_LITTLE_TO_HOST_U32(programHeader.p_paddr);
+                               programHeader.p_filesz = ENDIAN_LITTLE_TO_HOST_U32(programHeader.p_filesz);
+                               programHeader.p_memsz = ENDIAN_LITTLE_TO_HOST_U32(programHeader.p_memsz);
+                               programHeader.p_flags = ENDIAN_LITTLE_TO_HOST_U32(programHeader.p_flags);
+                               programHeader.p_align = ENDIAN_LITTLE_TO_HOST_U32(programHeader.p_align);
+                               
+                               m_programHeaders.push_back(programHeader);
+                       }
+               }
+               
+               // look up symbol table section index
+               {
+                   std::string symtab_section_name(SYMTAB_SECTION_NAME);
+                   m_symbolTableIndex = getIndexOfSectionWithName(symtab_section_name);
+               }
+       }
+       catch (...)
+       {
+               throw StELFFileException("error reading file");
+       }
+}
+
+const Elf32_Shdr & StELFFile::getSectionAtIndex(unsigned inIndex) const
+{
+       if (inIndex > m_sectionHeaders.size())
+               throw std::invalid_argument("inIndex");
+       
+       return m_sectionHeaders[inIndex];
+}
+
+//! If there is not a matching section, then #SHN_UNDEF is returned instead.
+//!
+unsigned StELFFile::getIndexOfSectionWithName(const std::string & inName)
+{
+       unsigned sectionIndex = 0;
+       const_section_iterator it = getSectionBegin();
+       for (; it != getSectionEnd(); ++it, ++sectionIndex)
+       {
+               const Elf32_Shdr & header = *it;
+               if (header.sh_name != 0)
+               {
+                       std::string sectionName = getSectionNameAtIndex(header.sh_name);
+                       if (inName == sectionName)
+                               return sectionIndex;
+               }
+       }
+       
+       // no matching section
+       return SHN_UNDEF;
+}
+
+//! The pointer returned from this method must be freed with the delete array operator (i.e., delete []).
+//! If either the section data offset (sh_offset) or the section size (sh_size) are 0, then NULL will
+//! be returned instead.
+//!
+//! The data is read directly from the input stream passed into the constructor. The stream must
+//! still be open, or an exception will be thrown.
+//!
+//! \exception StELFFileException is thrown if an error occurs while reading the file.
+//! \exception std::bad_alloc is thrown if memory for the data cannot be allocated.
+uint8_t * StELFFile::getSectionDataAtIndex(unsigned inIndex)
+{
+       return readSectionData(m_sectionHeaders[inIndex]);
+}
+
+//! The pointer returned from this method must be freed with the delete array operator (i.e., delete []).
+//! If either the section data offset (sh_offset) or the section size (sh_size) are 0, then NULL will
+//! be returned instead.
+//!
+//! The data is read directly from the input stream passed into the constructor. The stream must
+//! still be open, or an exception will be thrown.
+//!
+//! \exception StELFFileException is thrown if an error occurs while reading the file.
+//! \exception std::bad_alloc is thrown if memory for the data cannot be allocated.
+uint8_t * StELFFile::getSectionData(const_section_iterator inSection)
+{
+       return readSectionData(*inSection);
+}
+
+//! \exception StELFFileException is thrown if an error occurs while reading the file.
+//! \exception std::bad_alloc is thrown if memory for the data cannot be allocated.
+uint8_t * StELFFile::readSectionData(const Elf32_Shdr & inHeader)
+{
+       // check for empty data
+       if (inHeader.sh_offset == 0 || inHeader.sh_size == 0)
+               return NULL;
+               
+       uint8_t * sectionData = new uint8_t[inHeader.sh_size];
+       
+       try
+       {
+               m_stream.seekg(inHeader.sh_offset, std::ios::beg);
+               m_stream.read(reinterpret_cast<char *>(sectionData), inHeader.sh_size);
+               if (m_stream.bad())
+                       throw StELFFileException("could not read entire section");
+       }
+       catch (StELFFileException)
+       {
+               throw;
+       }
+       catch (...)
+       {
+               throw StELFFileException("error reading section data");
+       }
+               
+       return sectionData;
+}
+
+const Elf32_Phdr & StELFFile::getSegmentAtIndex(unsigned inIndex) const
+{
+       if (inIndex > m_programHeaders.size())
+               throw std::invalid_argument("inIndex");
+       
+       return m_programHeaders[inIndex];
+}
+
+//! The pointer returned from this method must be freed with the delete array operator (i.e., delete []).
+//! If either the segment offset (p_offset) or the segment file size (p_filesz) are 0, then NULL will
+//! be returned instead.
+//!
+//! The data is read directly from the input stream passed into the constructor. The stream must
+//! still be open, or an exception will be thrown.
+//!
+//! \exception StELFFileException is thrown if an error occurs while reading the file.
+//! \exception std::bad_alloc is thrown if memory for the data cannot be allocated.
+uint8_t * StELFFile::getSegmentDataAtIndex(unsigned inIndex)
+{
+       return readSegmentData(m_programHeaders[inIndex]);
+}
+
+//! The pointer returned from this method must be freed with the delete array operator (i.e., delete []).
+//! If either the segment offset (p_offset) or the segment file size (p_filesz) are 0, then NULL will
+//! be returned instead.
+//!
+//! The data is read directly from the input stream passed into the constructor. The stream must
+//! still be open, or an exception will be thrown.
+//!
+//! \exception StELFFileException is thrown if an error occurs while reading the file.
+//! \exception std::bad_alloc is thrown if memory for the data cannot be allocated.
+uint8_t * StELFFile::getSegmentData(const_segment_iterator inSegment)
+{
+       return readSegmentData(*inSegment);
+}
+       
+//! \exception StELFFileException is thrown if an error occurs while reading the file.
+//! \exception std::bad_alloc is thrown if memory for the data cannot be allocated.
+uint8_t * StELFFile::readSegmentData(const Elf32_Phdr & inHeader)
+{
+       // check for empty data
+       if (inHeader.p_offset == 0 || inHeader.p_filesz== 0)
+               return NULL;
+               
+       uint8_t * segmentData = new uint8_t[inHeader.p_filesz];
+       
+       try
+       {
+               m_stream.seekg(inHeader.p_offset, std::ios::beg);
+               m_stream.read(reinterpret_cast<char *>(segmentData), inHeader.p_filesz);
+               if (m_stream.bad())
+                       throw StELFFileException("could not read entire segment");
+       }
+       catch (StELFFileException)
+       {
+               throw;
+       }
+       catch (...)
+       {
+               throw StELFFileException("error reading segment data");
+       }
+       
+       return segmentData;
+}
+
+//! If the index is out of range, or if there is no string table in the file, then
+//! an empty string will be returned instead. This will also happen when the index
+//! is either 0 or the last byte in the table, since the table begins and ends with
+//! zero bytes.
+std::string StELFFile::getSectionNameAtIndex(unsigned inIndex)
+{
+       // make sure there's a section name string table
+       if (m_header.e_shstrndx == SHN_UNDEF)
+               return std::string("");
+       
+       return getStringAtIndex(m_header.e_shstrndx, inIndex);
+}
+
+//! \exception std::invalid_argument is thrown if the section identified by \a
+//!            inStringTableSectionIndex is not actually a string table, or if \a
+//!            inStringIndex is out of range for the string table.
+std::string StELFFile::getStringAtIndex(unsigned inStringTableSectionIndex, unsigned inStringIndex)
+{
+       // check section type
+       const Elf32_Shdr & header = getSectionAtIndex(inStringTableSectionIndex);
+       if (header.sh_type != SHT_STRTAB)
+               throw std::invalid_argument("inStringTableSectionIndex");
+       
+       if (inStringIndex >= header.sh_size)
+               throw std::invalid_argument("inStringTableSectionIndex");
+       
+       // check cache
+       SectionDataInfo & info = getCachedSectionData(inStringTableSectionIndex);
+       return std::string(&reinterpret_cast<char *>(info.m_data)[inStringIndex]);
+}
+
+StELFFile::SectionDataInfo & StELFFile::getCachedSectionData(unsigned inSectionIndex)
+{
+       // check cache
+       SectionDataMap::iterator it = m_sectionDataCache.find(inSectionIndex);
+       if (it != m_sectionDataCache.end())
+               return it->second;
+       
+       // not in cache, add it
+       const Elf32_Shdr & header = getSectionAtIndex(inSectionIndex);
+       uint8_t * data = getSectionDataAtIndex(inSectionIndex);
+       
+       SectionDataInfo info;
+       info.m_data = data;
+       info.m_size = header.sh_size;
+       
+       m_sectionDataCache[inSectionIndex] = info;
+       return m_sectionDataCache[inSectionIndex];
+}
+
+//! The number of entries in the symbol table is the symbol table section size
+//! divided by the size of each symbol entry (the #Elf32_Shdr::sh_entsize field of the
+//! symbol table section header).
+unsigned StELFFile::getSymbolCount()
+{
+       if (m_symbolTableIndex == SHN_UNDEF)
+               return 0;
+       
+       const Elf32_Shdr & header = getSectionAtIndex(m_symbolTableIndex);
+       return header.sh_size / header.sh_entsize;
+}
+
+//! \exception std::invalid_argument is thrown if \a inIndex is out of range.]
+//!
+const Elf32_Sym & StELFFile::getSymbolAtIndex(unsigned inIndex)
+{
+       // get section data
+       const Elf32_Shdr & header = getSectionAtIndex(m_symbolTableIndex);
+       SectionDataInfo & info = getCachedSectionData(m_symbolTableIndex);
+       
+       // has the symbol table been byte swapped yet?
+       if (!info.m_swapped)
+       {
+               byteSwapSymbolTable(header, info);
+       }
+       
+       unsigned symbolOffset = header.sh_entsize * inIndex;
+       if (symbolOffset >= info.m_size)
+       {
+               throw std::invalid_argument("inIndex");
+       }
+       
+       Elf32_Sym * symbol = reinterpret_cast<Elf32_Sym *>(&info.m_data[symbolOffset]);
+       return *symbol;
+}
+
+void StELFFile::byteSwapSymbolTable(const Elf32_Shdr & header, SectionDataInfo & info)
+{
+       unsigned symbolCount = getSymbolCount();
+       unsigned i = 0;
+       unsigned symbolOffset = 0;
+       
+       for (; i < symbolCount; ++i, symbolOffset += header.sh_entsize)
+       {
+               Elf32_Sym * symbol = reinterpret_cast<Elf32_Sym *>(&info.m_data[symbolOffset]);
+               symbol->st_name = ENDIAN_LITTLE_TO_HOST_U32(symbol->st_name);
+               symbol->st_value = ENDIAN_LITTLE_TO_HOST_U32(symbol->st_value);
+               symbol->st_size = ENDIAN_LITTLE_TO_HOST_U32(symbol->st_size);
+               symbol->st_shndx = ENDIAN_LITTLE_TO_HOST_U16(symbol->st_shndx);
+       }
+       
+       // remember that we've byte swapped the symbols
+       info.m_swapped = true;
+}
+
+unsigned StELFFile::getSymbolNameStringTableIndex() const
+{
+       const Elf32_Shdr & header = getSectionAtIndex(m_symbolTableIndex);
+       return header.sh_link;
+}
+
+std::string StELFFile::getSymbolName(const Elf32_Sym & inSymbol)
+{
+       unsigned symbolStringTableIndex = getSymbolNameStringTableIndex();
+       return getStringAtIndex(symbolStringTableIndex, inSymbol.st_name);
+}
+
+//! Returns STN_UNDEF if it cannot find a symbol at the given \a symbolAddress.
+unsigned StELFFile::getIndexOfSymbolAtAddress(uint32_t symbolAddress, bool strict)
+{
+       unsigned symbolCount = getSymbolCount();
+       unsigned symbolIndex = 0;
+       for (; symbolIndex < symbolCount; ++symbolIndex)
+       {
+               const Elf32_Sym & symbol = getSymbolAtIndex(symbolIndex);
+               
+               // the GHS toolchain puts in STT_FUNC symbols marking the beginning and ending of each
+               // file. if the entry point happens to be at the beginning of the file, the beginning-
+               // of-file symbol will have the same value and type. fortunately, the size of these
+               // symbols is 0 (or seems to be). we also ignore symbols that start with two dots just
+               // in case.
+               if (symbol.st_value == symbolAddress && (strict && ELF32_ST_TYPE(symbol.st_info) == STT_FUNC && symbol.st_size != 0))
+               {
+                       std::string symbolName = getSymbolName(symbol);
+                       
+                       // ignore symbols that start with two dots
+                       if (symbolName[0] == '.' && symbolName[1] == '.')
+                               continue;
+                       
+                       // found the symbol!
+                       return symbolIndex;
+               }
+       }
+       
+       return STN_UNDEF;
+}
+
+ARMSymbolType_t StELFFile::getTypeOfSymbolAtIndex(unsigned symbolIndex)
+{
+       ARMSymbolType_t symType = eARMSymbol;
+       const Elf32_Sym & symbol = getSymbolAtIndex(symbolIndex);
+       
+       if (m_elfVariant == eGHSVariant)
+       {
+               if (symbol.st_other & STO_THUMB)
+                       symType = eThumbSymbol;
+       }
+       else
+       {
+               unsigned mappingSymStart = 1;
+               unsigned mappingSymCount = getSymbolCount() - 1;        // don't include first undefined symbol
+               bool mapSymsFirst = (m_header.e_flags & EF_ARM_MAPSYMSFIRST) != 0;
+               if (mapSymsFirst)
+               {
+                       // first symbol '$m' is number of mapping syms
+                       const Elf32_Sym & mappingSymCountSym = getSymbolAtIndex(1);
+                       if (getSymbolName(mappingSymCountSym) == MAPPING_SYMBOL_COUNT_TAGSYM)
+                       {
+                               mappingSymCount = mappingSymCountSym.st_value;
+                               mappingSymStart = 2;
+                       }
+
+               }
+               
+               uint32_t lastMappingSymAddress = 0;
+               unsigned mappingSymIndex = mappingSymStart;
+               for (; mappingSymIndex < mappingSymCount + mappingSymStart; ++mappingSymIndex)
+               {
+                       const Elf32_Sym & mappingSym = getSymbolAtIndex(mappingSymIndex);
+                       std::string mappingSymName = getSymbolName(mappingSym);
+                       ARMSymbolType_t nextSymType = eUnknownSymbol;
+                       
+                       if (mappingSymName == ARM_SEQUENCE_MAPSYM)
+                               symType = eARMSymbol;
+                       else if (mappingSymName == DATA_SEQUENCE_MAPSYM)
+                               symType = eDataSymbol;
+                       else if (mappingSymName == THUMB_SEQUENCE_MAPSYM)
+                               symType = eThumbSymbol;
+                       
+                       if (nextSymType != eUnknownSymbol)
+                       {
+                               if (symbol.st_value >= lastMappingSymAddress && symbol.st_value < mappingSym.st_value)
+                                       break;
+                               
+                               symType = nextSymType;
+                               lastMappingSymAddress = mappingSym.st_value;
+                       }
+               }
+       }
+       
+       return symType;
+}
+
+void StELFFile::dumpSections()
+{
+       unsigned count = getSectionCount();
+       unsigned i = 0;
+       
+       const char * sectionTypes[12] = { "NULL", "PROGBITS", "SYMTAB", "STRTAB", "RELA", "HASH", "DYNAMIC", "NOTE", "NOBITS", "REL", "SHLIB", "DYNSYM" };
+       
+       for (; i < count; ++i)
+       {
+               const Elf32_Shdr & header = getSectionAtIndex(i);
+               std::string name = getSectionNameAtIndex(header.sh_name);
+
+               if (header.sh_type < sizeof(sectionTypes) / sizeof(sectionTypes[0])) {
+                       printf("%s: %s, 0x%08x, 0x%08x, 0x%08x, %d, %d, %d\n",
+                              name.c_str(), sectionTypes[header.sh_type],
+                              header.sh_addr, header.sh_offset,
+                              header.sh_size, header.sh_link,
+                              header.sh_info, header.sh_entsize);
+               } else {
+                       printf("%s: 0x%02x, 0x%08x, 0x%08x, 0x%08x, %d, %d, %d\n",
+                              name.c_str(), header.sh_type,
+                              header.sh_addr, header.sh_offset,
+                              header.sh_size, header.sh_link,
+                              header.sh_info, header.sh_entsize);
+               }
+       }
+}
+
+void StELFFile::dumpSymbolTable()
+{
+       const char * symbolTypes[5] = { "NOTYPE", "OBJECT", "FUNC", "SECTION", "FILE" };
+       const char * symbolBinding[3] = { "LOCAL", "GLOBAL", "WEAK" };
+       
+       unsigned count = getSymbolCount();
+       unsigned i = 0;
+       
+       for (; i < count; ++i)
+       {
+               const Elf32_Sym & symbol = getSymbolAtIndex(i);
+               std::string name = getSymbolName(symbol);
+               
+               printf("'%s': %s, %s, 0x%08x, 0x%08x, %d. 0x%08x\n", name.c_str(), symbolTypes[ELF32_ST_TYPE(symbol.st_info)], symbolBinding[ELF32_ST_BIND(symbol.st_info)], symbol.st_value, symbol.st_size, symbol.st_shndx, symbol.st_other);
+       }
+}
+
+
+
diff --git a/tools/elftosb/common/StELFFile.h b/tools/elftosb/common/StELFFile.h
new file mode 100644 (file)
index 0000000..3ab9899
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * File:       StELFFile.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_StELFFile_h_)
+#define _StELFFile_h_
+
+#include "stdafx.h"
+#include <string>
+#include <vector>
+#include <map>
+#include <iostream>
+#include <stdexcept>
+#include "ELF.h"
+
+//! Variations of the ARM ELF format.
+typedef enum {
+       eARMVariant = 1,        //!< Standard ARM ELF specification.
+       eGHSVariant,            //!< Green Hills Software variant.
+       eGCCVariant             //!< GNU Compiler Collection variant.
+} ELFVariant_t;
+
+//! Possible ARM ELF symbol types.
+typedef enum {
+       eUnknownSymbol,
+       eARMSymbol,
+       eThumbSymbol,
+       eDataSymbol
+} ARMSymbolType_t;
+
+/*!
+ * \brief Parser for Executable and Linking Format (ELF) files.
+ *
+ * The stream passed into the constructor needs to stay open for the life
+ * of the object. This is because calls to getSectionDataAtIndex() and
+ * getSegmentDataAtIndex() read the data directly from the input stream.
+ */
+class StELFFile
+{
+public:
+       typedef std::vector<Elf32_Shdr>::const_iterator const_section_iterator;
+       typedef std::vector<Elf32_Phdr>::const_iterator const_segment_iterator;
+       
+public:
+       //! \brief Constructor.
+       StELFFile(std::istream & inStream);
+       
+       //! \brief Destructor.
+       virtual ~StELFFile();
+       
+       //! \name File format variant
+       //@{
+       //! \brief Return the ELF format variant to which this file is set.
+       virtual ELFVariant_t ELFVariant() { return m_elfVariant; }
+       
+       //! \brief Set the ELF format variation to either #eARMVariant or #eGHSVariant.
+       virtual void setELFVariant(ELFVariant_t variant) { m_elfVariant = variant; }
+       //@}
+       
+       //! \name File name
+       //@{
+       virtual void setName(const std::string & inName) { m_name = inName; }
+       virtual std::string getName() const { return m_name; }
+       //@}
+       
+       //! \name ELF header
+       //@{
+       //! \brief Returns the ELF file header.
+       inline const Elf32_Ehdr & getFileHeader() const { return m_header; }
+       //@}
+       
+       //! \name Sections
+       //! Methods pertaining to the object file's sections.
+       //@{
+       //! \brief Returns the number of sections in the file.
+       inline unsigned getSectionCount() const { return static_cast<unsigned>(m_sectionHeaders.size()); }
+       
+       //! \brief Returns a reference to section number \a inIndex.
+       const Elf32_Shdr & getSectionAtIndex(unsigned inIndex) const;
+       
+       inline const_section_iterator getSectionBegin() const { return m_sectionHeaders.begin(); }
+       inline const_section_iterator getSectionEnd() const { return m_sectionHeaders.end(); }
+       
+       //! \brief Returns the index of the section with the name \a inName.
+       unsigned getIndexOfSectionWithName(const std::string & inName);
+       
+       //! \brief Returns the data for the section.
+       uint8_t * getSectionDataAtIndex(unsigned inIndex);
+       
+       //! \brief Returns the data for the section.
+       uint8_t * getSectionData(const_section_iterator inSection);
+       //@}
+       
+       //! \name Segments
+       //! Methods for accessing the file's program headers for segments.
+       //@{
+       //! \brief Returns the number of segments, or program headers, in the file.
+       inline unsigned getSegmentCount() const { return static_cast<unsigned>(m_programHeaders.size()); }
+       
+       //! \brief Returns a reference to the given segment.
+       const Elf32_Phdr & getSegmentAtIndex(unsigned inIndex) const;
+
+       inline const_segment_iterator getSegmentBegin() const { return m_programHeaders.begin(); }
+       inline const_segment_iterator getSegmentEnd() const { return m_programHeaders.end(); }
+       
+       //! \brief Returns the data of the specified segment.
+       uint8_t * getSegmentDataAtIndex(unsigned inIndex);
+       
+       //! \brief Returns the data of the specified segment.
+       uint8_t * getSegmentData(const_segment_iterator inSegment);
+       //@}
+       
+       //! \name String table
+       //! Methods for accessing the string tables.
+       //@{
+       //! \brief Returns a string from the file's section name string table.
+       std::string getSectionNameAtIndex(unsigned inIndex);
+       
+       //! \brief Returns a string from any string table in the object file.
+       std::string getStringAtIndex(unsigned inStringTableSectionIndex, unsigned inStringIndex);
+       //@}
+       
+       //! \name Symbol table
+       //! Methods for accessing the object file's symbol table. Currently only
+       //! a single symbol table with the section name ".symtab" is supported.
+       //@{
+       //! \brief Returns the number of symbols in the default ".symtab" symbol table.
+       unsigned getSymbolCount();
+       
+       //! \brief Returns the symbol with index \a inIndex.
+       const Elf32_Sym & getSymbolAtIndex(unsigned inIndex);
+       
+       //! \brief Returns the section index of the string table containing symbol names.
+       unsigned getSymbolNameStringTableIndex() const;
+       
+       //! \brief Returns the name of the symbol described by \a inSymbol.
+       std::string getSymbolName(const Elf32_Sym & inSymbol);
+       
+       unsigned getIndexOfSymbolAtAddress(uint32_t symbolAddress, bool strict=true);
+       
+       ARMSymbolType_t getTypeOfSymbolAtIndex(unsigned symbolIndex);
+       //@}
+       
+       //! \name Debugging
+       //@{
+       void dumpSections();
+       void dumpSymbolTable();
+       //@}
+
+protected:
+       std::istream & m_stream;        //!< The source stream for the ELF file.
+       ELFVariant_t m_elfVariant;      //!< Variant of the ARM ELF format specification.
+       std::string m_name;                     //!< File name. (optional)
+       Elf32_Ehdr m_header;    //!< The ELF file header.
+       std::vector<Elf32_Shdr> m_sectionHeaders;       //!< All of the section headers.
+       std::vector<Elf32_Phdr> m_programHeaders;       //!< All of the program headers.
+       unsigned m_symbolTableIndex;    //!< Index of ".symtab" section, or #SHN_UNDEF if not present.
+       
+       /*!
+        * Little structure containing information about cached section data.
+        */
+       struct SectionDataInfo
+       {
+               uint8_t * m_data;       //!< Pointer to section data.
+               unsigned m_size;        //!< Section data size in bytes.
+               bool m_swapped; //!< Has this section been byte swapped yet? Used for symbol table.
+       };
+       typedef std::map<unsigned, SectionDataInfo> SectionDataMap;
+       SectionDataMap m_sectionDataCache;      //!< Cached data of sections.
+       
+       //! \brief Reads a section's data either from cache or from disk.
+       SectionDataInfo & getCachedSectionData(unsigned inSectionIndex);
+       
+       //! \brief Reads the file, section, and program headers into memory.
+       void readFileHeaders();
+       
+       uint8_t * readSectionData(const Elf32_Shdr & inHeader);
+       uint8_t * readSegmentData(const Elf32_Phdr & inHeader);
+       
+       //! \brief Byte swaps the symbol table data into host endianness.
+       void byteSwapSymbolTable(const Elf32_Shdr & header, SectionDataInfo & info);
+};
+
+/*!
+ * \brief Simple exception thrown to indicate an error in the input ELF file format.
+ */
+class StELFFileException : public std::runtime_error
+{
+public:
+       //! \brief Default constructor.
+       StELFFileException(const std::string & inMessage) : std::runtime_error(inMessage) {}
+};
+
+#endif // _StELFFile_h_
diff --git a/tools/elftosb/common/StExecutableImage.cpp b/tools/elftosb/common/StExecutableImage.cpp
new file mode 100644 (file)
index 0000000..7f5eb0a
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * File:       StExecutableImage.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "StExecutableImage.h"
+#include <stdexcept>
+#include <algorithm>
+#include <string.h>
+#include <stdio.h>
+
+StExecutableImage::StExecutableImage(int inAlignment)
+:      m_alignment(inAlignment),
+       m_hasEntry(false),
+       m_entry(0)
+{
+}
+
+//! Makes a duplicate of each memory region.
+StExecutableImage::StExecutableImage(const StExecutableImage & inOther)
+:      m_name(inOther.m_name),
+    m_alignment(inOther.m_alignment),
+       m_hasEntry(inOther.m_hasEntry),
+       m_entry(inOther.m_entry),
+    m_filters(inOther.m_filters)
+{
+       const_iterator it = inOther.getRegionBegin();
+       for (; it != inOther.getRegionEnd(); ++it)
+       {
+               const MemoryRegion & region = *it;
+               
+               MemoryRegion regionCopy(region);
+               if (region.m_type == FILL_REGION && region.m_data != NULL)
+               {
+                       regionCopy.m_data = new uint8_t[region.m_length];
+                       memcpy(regionCopy.m_data, region.m_data, region.m_length);
+               }
+               
+               m_image.push_back(regionCopy);
+       }
+}
+
+//! Disposes of memory allocated for each region.
+StExecutableImage::~StExecutableImage()
+{
+       MemoryRegionList::iterator it;
+       for (it = m_image.begin(); it != m_image.end(); ++it)
+       {
+               if (it->m_data)
+               {
+                       delete [] it->m_data;
+                       it->m_data = NULL;
+               }
+       }
+}
+
+//! A copy of \a inName is made, so the original may be disposed of by the caller
+//! after this method returns.
+void StExecutableImage::setName(const std::string & inName)
+{
+       m_name = inName;
+}
+
+std::string StExecutableImage::getName() const
+{
+       return m_name;
+}
+
+// The region is added with read and write flags set.
+//! \exception std::runtime_error will be thrown if the new overlaps an
+//!            existing region.
+void StExecutableImage::addFillRegion(uint32_t inAddress, unsigned inLength)
+{
+       MemoryRegion region;
+       region.m_type = FILL_REGION;
+       region.m_address = inAddress;
+       region.m_data = NULL;
+       region.m_length = inLength;
+       region.m_flags = REGION_RW_FLAG;
+       
+       insertOrMergeRegion(region);
+}
+
+//! A copy of \a inData is made before returning. The copy will be deleted when 
+//! the executable image is destructed. Currently, the text region is created with
+//! read, write, and executable flags set.
+//! \exception std::runtime_error will be thrown if the new overlaps an
+//!            existing region.
+//! \exception std::bad_alloc is thrown if memory for the copy of \a inData
+//!            cannot be allocated.
+void StExecutableImage::addTextRegion(uint32_t inAddress, const uint8_t * inData, unsigned inLength)
+{
+       MemoryRegion region;
+       region.m_type = TEXT_REGION;
+       region.m_address = inAddress;
+       region.m_flags = REGION_RW_FLAG | REGION_EXEC_FLAG;
+       
+       // copy the data
+       region.m_data = new uint8_t[inLength];
+       region.m_length = inLength;
+       memcpy(region.m_data, inData, inLength);
+       
+       insertOrMergeRegion(region);
+}
+
+//! \exception std::out_of_range is thrown if \a inIndex is out of range.
+//!
+const StExecutableImage::MemoryRegion & StExecutableImage::getRegionAtIndex(unsigned inIndex) const
+{
+       // check bounds
+       if (inIndex >= m_image.size())
+               throw std::out_of_range("inIndex");
+       
+       // find region by index
+       MemoryRegionList::const_iterator it = m_image.begin();
+       unsigned i = 0;
+       for (; it != m_image.end(); ++it, ++i)
+       {
+               if (i == inIndex)
+                       break;
+       }
+       return *it;
+}
+
+//! The list of address filters is kept sorted as filters are added.
+//!
+void StExecutableImage::addAddressFilter(const AddressFilter & filter)
+{
+    m_filters.push_back(filter);
+    m_filters.sort();
+}
+
+//!
+void StExecutableImage::clearAddressFilters()
+{
+    m_filters.clear();
+}
+
+//! \exception StExecutableImage::address_filter_exception Raised when a filter
+//!     with the type #ADDR_FILTER_ERROR or #ADDR_FILTER_WARNING is matched.
+//!
+//! \todo Build a list of all matching filters and then execute them at once.
+//!     For the warning and error filters, a single exception should be raised
+//!     that identifies all the overlapping errors. Currently the user will only
+//!     see the first (lowest address) overlap.
+void StExecutableImage::applyAddressFilters()
+{
+restart_loops:
+    // Iterate over filters.
+    AddressFilterList::const_iterator fit = m_filters.begin();
+    for (; fit != m_filters.end(); ++fit)
+    {
+        const AddressFilter & filter = *fit;
+        
+        // Iterator over regions.
+        MemoryRegionList::iterator rit = m_image.begin();
+        for (; rit != m_image.end(); ++rit)
+        {
+            MemoryRegion & region = *rit;
+            
+            if (filter.matchesMemoryRegion(region))
+            {
+                switch (filter.m_action)
+                {
+                    case ADDR_FILTER_NONE:
+                        // Do nothing.
+                        break;
+                        
+                    case ADDR_FILTER_ERROR:
+                        // throw error exception
+                        throw address_filter_exception(true, m_name, filter);
+                        break;
+                        
+                    case ADDR_FILTER_WARNING:
+                        // throw warning exception
+                        throw address_filter_exception(false, m_name, filter);
+                        break;
+                        
+                    case ADDR_FILTER_CROP:
+                        // Delete the offending portion of the region and restart
+                        // the iteration loops.
+                        cropRegionToFilter(region, filter);
+                        goto restart_loops;
+                        break;
+                }
+            }
+        }
+    }
+}
+
+//! There are several possible cases here:
+//!     - No overlap at all. Nothing is done.
+//!
+//!     - All of the memory region is matched by the \a filter. The region is
+//!         removed from #StExecutableImage::m_image and its data memory freed.
+//!
+//!     - The remaining portion of the region is one contiguous chunk. In this
+//!         case, \a region is simply modified. 
+//!
+//!     - The region is split in the middle by the filter. The original \a region
+//!         is modified to match the first remaining chunk. And a new #StExecutableImage::MemoryRegion
+//!         instance is created to hold the other leftover piece.
+void StExecutableImage::cropRegionToFilter(MemoryRegion & region, const AddressFilter & filter)
+{
+    uint32_t firstByte = region.m_address;      // first byte occupied by this region
+    uint32_t lastByte = region.endAddress();    // last used byte in this region
+    
+    // compute new address range
+    uint32_t cropFrom = filter.m_fromAddress;
+    if (cropFrom < firstByte)
+    {
+        cropFrom = firstByte;
+    }
+    
+    uint32_t cropTo = filter.m_toAddress;
+    if (cropTo > lastByte)
+    {
+        cropTo = lastByte;
+    }
+    
+    // is there actually a match?
+    if (cropFrom > filter.m_toAddress || cropTo < filter.m_fromAddress)
+    {
+        // nothing to do, so bail
+        return;
+    }
+    
+    printf("Deleting region 0x%08x-0x%08x\n", cropFrom, cropTo);
+    
+    // handle if the entire region is to be deleted
+    if (cropFrom == firstByte && cropTo == lastByte)
+    {
+        delete [] region.m_data;
+        region.m_data = NULL;
+        m_image.remove(region);
+    }
+    
+    // there is at least a little of the original region remaining
+    uint32_t newLength = cropTo - cropFrom + 1;
+    uint32_t leftoverLength = lastByte - cropTo;
+    uint8_t * oldData = region.m_data;
+    
+    // update the region
+    region.m_address = cropFrom;
+    region.m_length = newLength;
+    
+    // crop data buffer for text regions
+    if (region.m_type == TEXT_REGION && oldData)
+    {
+        region.m_data = new uint8_t[newLength];
+        memcpy(region.m_data, &oldData[cropFrom - firstByte], newLength);
+        
+        // dispose of old data
+        delete [] oldData;
+    }
+    
+    // create a new region for any part of the original region that was past
+    // the crop to address. this will happen if the filter range falls in the
+    // middle of the region.
+    if (leftoverLength)
+    {
+        MemoryRegion newRegion;
+        newRegion.m_type = region.m_type;
+        newRegion.m_flags = region.m_flags;
+        newRegion.m_address = cropTo + 1;
+        newRegion.m_length = leftoverLength;
+        
+        if (region.m_type == TEXT_REGION && oldData)
+        {
+            newRegion.m_data = new uint8_t[leftoverLength];
+            memcpy(newRegion.m_data, &oldData[cropTo - firstByte + 1], leftoverLength);
+        }
+        
+        insertOrMergeRegion(newRegion);
+    }
+}
+
+//! \exception std::runtime_error will be thrown if \a inRegion overlaps an
+//!            existing region.
+//!
+//! \todo Need to investigate if we can use the STL sort algorithm at all. Even
+//!     though we're doing merges too, we could sort first then examine the list
+//!     for merges.
+void StExecutableImage::insertOrMergeRegion(MemoryRegion & inRegion)
+{
+       uint32_t newStart = inRegion.m_address;
+       uint32_t newEnd = newStart + inRegion.m_length;
+       
+       MemoryRegionList::iterator it = m_image.begin();
+       MemoryRegionList::iterator sortedPosition = m_image.begin();
+       for (; it != m_image.end(); ++it)
+       {
+               MemoryRegion & region = *it;
+               uint32_t thisStart = region.m_address;
+               uint32_t thisEnd = thisStart + region.m_length;
+               
+               // keep track of where to insert it to retain sort order
+               if (thisStart >= newEnd)
+               {
+                       break;
+               }
+                       
+               // region types and flags must match in order to merge
+               if (region.m_type == inRegion.m_type && region.m_flags == inRegion.m_flags)
+               {
+                       if (newStart == thisEnd || newEnd == thisStart)
+                       {
+                               mergeRegions(region, inRegion);
+                               return;
+                       }
+                       else if ((newStart >= thisStart && newStart < thisEnd) || (newEnd >= thisStart && newEnd < thisEnd))
+                       {
+                               throw std::runtime_error("new region overlaps existing region");
+                       }
+               }
+       }
+       
+       // not merged, so just insert it in the sorted position
+       m_image.insert(it, inRegion);
+}
+
+//! Extends \a inNewRegion to include the data in \a inOldRegion. It is
+//! assumed that the two regions are compatible. The new region may come either
+//! before or after the old region in memory. Note that while the two regions
+//! don't necessarily have to be touching, it's probably a good idea. That's
+//! because any data between the regions will be set to 0.
+//!
+//! For TEXT_REGION types, the two original regions will have their data deleted
+//! during the merge. Thus, this method is not safe if any outside callers may
+//! be accessing the region's data.
+void StExecutableImage::mergeRegions(MemoryRegion & inOldRegion, MemoryRegion & inNewRegion)
+{
+       bool isOldBefore = inOldRegion.m_address < inNewRegion.m_address;
+       uint32_t oldEnd = inOldRegion.m_address + inOldRegion.m_length;
+       uint32_t newEnd = inNewRegion.m_address + inNewRegion.m_length;
+       
+       switch (inOldRegion.m_type)
+       {
+               case TEXT_REGION:
+               {
+                       // calculate new length
+                       unsigned newLength;
+                       if (isOldBefore)
+                       {
+                               newLength = newEnd - inOldRegion.m_address;
+                       }
+                       else
+                       {
+                               newLength = oldEnd - inNewRegion.m_address;
+                       }
+                       
+                       // alloc memory
+                       uint8_t * newData = new uint8_t[newLength];
+                       memset(newData, 0, newLength);
+                       
+                       // copy data from the two regions into new block
+                       if (isOldBefore)
+                       {
+                               memcpy(newData, inOldRegion.m_data, inOldRegion.m_length);
+                               memcpy(&newData[newLength - inNewRegion.m_length], inNewRegion.m_data, inNewRegion.m_length);
+                       }
+                       else
+                       {
+                               memcpy(newData, inNewRegion.m_data, inNewRegion.m_length);
+                               memcpy(&newData[newLength - inOldRegion.m_length], inOldRegion.m_data, inOldRegion.m_length);
+                               
+                               inOldRegion.m_address = inNewRegion.m_address;
+                       }
+                       
+                       // replace old region's data
+                       delete [] inOldRegion.m_data;
+                       inOldRegion.m_data = newData;
+                       inOldRegion.m_length = newLength;
+                       
+                       // delete new region's data
+                       delete [] inNewRegion.m_data;
+                       inNewRegion.m_data = NULL;
+                       break;
+               }
+                       
+               case FILL_REGION:
+               {
+                       if (isOldBefore)
+                       {
+                               inOldRegion.m_length = newEnd - inOldRegion.m_address;
+                       }
+                       else
+                       {
+                               inOldRegion.m_length = oldEnd - inNewRegion.m_address;
+                               inOldRegion.m_address = inNewRegion.m_address;
+                       }
+                       break;
+               }
+       }
+}
+
+//! Used when we remove a region from the region list by value. Because this
+//! operator compares the #m_data member, it will only return true for either an
+//! exact copy or a reference to the original.
+bool StExecutableImage::MemoryRegion::operator == (const MemoryRegion & other)
+{
+   return (m_type == other.m_type) && (m_address == other.m_address) && (m_length == other.m_length) && (m_flags == other.m_flags) && (m_data == other.m_data);
+}
+
+//! Returns true if the address filter overlaps \a region.
+bool StExecutableImage::AddressFilter::matchesMemoryRegion(const MemoryRegion & region) const
+{
+    uint32_t firstByte = region.m_address;      // first byte occupied by this region
+    uint32_t lastByte = region.endAddress();    // last used byte in this region
+    return (firstByte >= m_fromAddress && firstByte <= m_toAddress) || (lastByte >= m_fromAddress && lastByte <= m_toAddress);
+}
+
+//! The comparison does \em not take the action into account. It only looks at the
+//! priority and address ranges of each filter. Priority is considered only if the two
+//! filters overlap. Lower priority filters will come after higher priority ones.
+//!
+//! \retval -1 This filter is less than filter \a b.
+//! \retval 0 This filter is equal to filter \a b.
+//! \retval 1 This filter is greater than filter \a b.
+int StExecutableImage::AddressFilter::compare(const AddressFilter & other) const
+{
+    if (m_priority != other.m_priority && ((m_fromAddress >= other.m_fromAddress && m_fromAddress <= other.m_toAddress) || (m_toAddress >= other.m_fromAddress && m_toAddress <= other.m_toAddress)))
+    {
+        // we know the priorities are not equal
+        if (m_priority > other.m_priority)
+        {
+            return -1;
+        }
+        else
+        {
+            return 1;
+        }
+    }
+    
+    if (m_fromAddress == other.m_fromAddress)
+    {
+        if (m_toAddress == other.m_toAddress)
+        {
+            return 0;
+        }
+        else if (m_toAddress < other.m_toAddress)
+        {
+            return -1;
+        }
+        else
+        {
+            return 1;
+        }
+    }
+    else if (m_fromAddress < other.m_fromAddress)
+    {
+        return -1;
+    }
+    else
+    {
+        return 1;
+    }
+}
+
+
+
diff --git a/tools/elftosb/common/StExecutableImage.h b/tools/elftosb/common/StExecutableImage.h
new file mode 100644 (file)
index 0000000..edfd5f4
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * File:       StExecutableImage.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_StExecutableImage_h_)
+#define _StExecutableImage_h_
+
+#include "stdafx.h"
+#include <list>
+
+/*!
+ * \brief Used to build a representation of memory regions.
+ *
+ * An intermediate representation of the memory regions and segments loaded
+ * from an executable file. Also used to find contiguous segments that are
+ * specified separately in the source file.
+ *
+ * When regions are added, an attempt is made to coalesce contiguous regions.
+ * In order for this to succeed, the touching regions must be of the same
+ * type and have the same permissions. Regions are also kept sorted by their
+ * address range as they are added.
+ *
+ * \todo Implement alignment support.
+ */
+class StExecutableImage
+{
+public:
+       //! Possible types of memory regions.
+       typedef enum {
+               TEXT_REGION,    //!< A region containing data or instructions.
+               FILL_REGION             //!< Region to be initialized with zero bytes.
+       } MemoryRegionType;
+       
+       //! Memory region flag constants.
+       enum {
+               REGION_READ_FLAG = 1,   //!< Region is readable.
+               REGION_WRITE_FLAG = 2,  //!< Region is writable.
+               REGION_EXEC_FLAG = 4,   //!< Region may contain executable code.
+               
+               REGION_RW_FLAG = REGION_READ_FLAG | REGION_WRITE_FLAG,  //!< Region is read-write.
+               
+               //! Mask to access only permissions flags for a region.
+               REGION_PERM_FLAG_MASK = 0x7
+       };
+       
+       /*!
+        * Representation of a contiguous region of memory.
+     *
+     * \todo Add comparison operators so we can use the STL sort algorithm.
+        */
+       struct MemoryRegion
+       {
+               MemoryRegionType m_type;        //!< Memory region type.
+               uint32_t m_address;     //!< The 32-bit start address of this region.
+               uint32_t m_length;      //!< Number of bytes in this region.
+               uint8_t * m_data;       //!< Pointer to data. Will be NULL for FILL_REGION type.
+               unsigned m_flags;       //!< Flags for the region.
+        
+        //! \brief Calculates the address of the last byte occupied by this region.
+        inline uint32_t endAddress() const { return m_address + m_length - 1; }
+        
+        //! \brief Equality operator.
+        bool operator == (const MemoryRegion & other);
+       };
+       
+       //! A list of #StExecutableImage::MemoryRegion objects.
+       typedef std::list<MemoryRegion> MemoryRegionList;
+    
+    //! The iterator type used to access #StExecutableImage::MemoryRegion objects. This type
+    //! is used by the methods #getRegionBegin() and #getRegionEnd().
+       typedef MemoryRegionList::const_iterator const_iterator;
+       
+    //! The possible actions for regions matching an address filter range.
+    typedef enum {
+        ADDR_FILTER_NONE,       //!< Do nothing.
+        ADDR_FILTER_ERROR,      //!< Raise an error exception.
+        ADDR_FILTER_WARNING,    //!< Raise a warning exception.
+        ADDR_FILTER_CROP        //!< Don't include the matching address range in the executable image.
+    } AddressFilterAction;
+    
+    /*!
+     * An address filter consists of a single address range and an action. If a
+     * memory region overlaps the filter's range then the action will be performed.
+     * The possible filter actions are defined by the #AddressFilterAction enumeration.
+     */
+    struct AddressFilter
+    {
+        AddressFilterAction m_action;   //!< Action to be performed when the filter is matched.
+        uint32_t m_fromAddress; //!< Start address of the filter. Should be lower than or equal to #m_toAddress.
+        uint32_t m_toAddress;   //!< End address of the filter. Should be higher than or equal to #m_fromAddress.
+        unsigned m_priority;     //!< Priority for this filter. Zero is the lowest priority.
+        
+        //! \brief Constructor.
+        AddressFilter(AddressFilterAction action, uint32_t from, uint32_t to, unsigned priority=0)
+        :   m_action(action), m_fromAddress(from), m_toAddress(to), m_priority(priority)
+        {
+        }
+        
+        //! \brief Test routine.
+        bool matchesMemoryRegion(const MemoryRegion & region) const;
+        
+        //! \brief Compares two address filter objects.
+        int compare(const AddressFilter & other) const;
+        
+        //! \name Comparison operators
+        //@{
+        inline bool operator < (const AddressFilter & other) const { return compare(other) == -1; }
+        inline bool operator > (const AddressFilter & other) const { return compare(other) == 1; }
+        inline bool operator == (const AddressFilter & other) const { return compare(other) == 0; }
+        inline bool operator <= (const AddressFilter & other) const { return compare(other) != 1; }
+        inline bool operator >= (const AddressFilter & other) const { return compare(other) != -1; }
+        //@}
+    };
+    
+    //! List of #StExecutableImage::AddressFilter objects.
+    typedef std::list<AddressFilter> AddressFilterList;
+    
+    //! The exception class raised for the #ADDR_FILTER_ERROR and #ADDR_FILTER_WARNING
+    //! filter actions.
+    class address_filter_exception
+    {
+    public:
+        //! \brief Constructor.
+        //!
+        //! A local copy of \a matchingFilter is made, in case the image and/or filter
+        //! are on the stack and would be disposed of when the exception is raised.
+        address_filter_exception(bool isError, std::string & imageName, const AddressFilter & matchingFilter)
+        : m_isError(isError), m_imageName(imageName), m_filter(matchingFilter)
+        {
+        }
+        
+        //! \brief Returns true if the exception is an error. Otherwise the exception
+        //!     is for a warning.
+        inline bool isError() const { return m_isError; }
+        
+        //! \brief
+        inline std::string getImageName() const { return m_imageName; }
+        
+        //! \brief
+        inline const AddressFilter & getMatchingFilter() const { return m_filter; }
+    
+    protected:
+        bool m_isError;
+        std::string m_imageName;
+        AddressFilter m_filter;
+    };
+    
+public:
+       //! \brief Constructor.
+       StExecutableImage(int inAlignment=256);
+       
+       //! \brief Copy constructor.
+       StExecutableImage(const StExecutableImage & inOther);
+       
+       //! \brief Destructor.
+       virtual ~StExecutableImage();
+       
+       //! \name Image name
+       //! Methods for getting and setting the image name.
+       //@{
+       //! \brief Sets the image's name to \a inName.
+       virtual void setName(const std::string & inName);
+       
+       //! \brief Returns a copy of the image's name.
+       virtual std::string getName() const;
+       //@}
+       
+       //! \name Regions
+       //! Methods to add and access memory regions.
+       //@{
+       //! \brief Add a region to be filled with zeroes.
+       virtual void addFillRegion(uint32_t inAddress, unsigned inLength);
+       
+       //! \brief Add a region containing data to be loaded.
+       virtual void addTextRegion(uint32_t inAddress, const uint8_t * inData, unsigned inLength);
+       
+       //! \brief Returns the total number of regions.
+       //!
+       //! Note that this count may not be the same as the number of calls to
+       //! addFillRegion() and addTextRegion() due to region coalescing.
+       inline unsigned getRegionCount() const { return static_cast<unsigned>(m_image.size()); }
+       
+       //! \brief Returns a reference to the region specified by \a inIndex.
+       const MemoryRegion & getRegionAtIndex(unsigned inIndex) const;
+       
+    //! \brief Return an iterator to the first region.
+       inline const_iterator getRegionBegin() const { return m_image.begin(); }
+    
+    //! \brief Return an iterator to the next-after-last region.
+       inline const_iterator getRegionEnd() const { return m_image.end(); }
+       //@}
+       
+       //! \name Entry point
+       //@{
+       //! \brief Sets the entry point address.
+       inline void setEntryPoint(uint32_t inEntryAddress) { m_entry = inEntryAddress; m_hasEntry = true; }
+       
+       //! \brief Returns true if an entry point has been set.
+       inline bool hasEntryPoint() const { return m_hasEntry; }
+       
+       //! \brief Returns the entry point address.
+       inline uint32_t getEntryPoint() const { return hasEntryPoint() ? m_entry : 0; }
+       //@}
+    
+    //! \name Address filter
+    //@{
+    //! \brief Add a new address filter.
+    virtual void addAddressFilter(const AddressFilter & filter);
+    
+    //! \brief Add multiple address filters at once.
+    //!
+    //! The template argument \a _T must be an iterator or const iterator that
+    //! dereferences to an StExecutableImage::AddressFilter reference. All filters
+    //! from \a from to \a to will be added to the address filter list.
+    template<typename _T> void addAddressFilters(_T from, _T to)
+    {
+        _T it = from;
+        for (; it != to; ++it)
+        {
+            addAddressFilter(*it);
+        }
+    }
+    
+    //! \brief Remove all active filters.
+    virtual void clearAddressFilters();
+    
+    //! \brief Process all active filters and perform associated actions.
+    virtual void applyAddressFilters();
+    //@}
+       
+protected:
+       std::string m_name;     //!< The name of the image (can be a file name, for instance).
+       int m_alignment;        //!< The required address alignment for each memory region.
+       bool m_hasEntry;        //!< True if an entry point has been set.
+       uint32_t m_entry;       //!< Entry point address.
+       MemoryRegionList m_image;       //!< The memory regions.
+    AddressFilterList m_filters;    //!< List of active address filters.
+    
+    //! \brief Deletes the portion \a region that overlaps \a filter.
+    void cropRegionToFilter(MemoryRegion & region, const AddressFilter & filter);
+       
+       //! \brief Inserts the region in sorted order or merges with one already in the image.
+       void insertOrMergeRegion(MemoryRegion & inRegion);
+       
+       //! \brief Merges two memory regions into one.
+       void mergeRegions(MemoryRegion & inOldRegion, MemoryRegion & inNewRegion);
+};
+
+#endif // _StExecutableImage_h_
diff --git a/tools/elftosb/common/StSRecordFile.cpp b/tools/elftosb/common/StSRecordFile.cpp
new file mode 100644 (file)
index 0000000..1ad0872
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * File:       StSRecordFile.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "stdafx.h"
+#include "StSRecordFile.h"
+#include "string.h"
+
+StSRecordFile::StSRecordFile(std::istream & inStream)
+:      m_stream(inStream)
+{
+}
+
+//! Frees any data allocated as part of an S-record.
+StSRecordFile::~StSRecordFile()
+{
+       const_iterator it;
+       for (it = m_records.begin(); it != m_records.end(); it++)
+       {
+               SRecord & theRecord = (SRecord &)*it;
+               if (theRecord.m_data)
+               {
+                       delete [] theRecord.m_data;
+                       theRecord.m_data = NULL;
+               }
+       }
+}
+
+//! Just looks for "S[0-9]" as the first two characters of the file.
+bool StSRecordFile::isSRecordFile()
+{
+       int savePosition = m_stream.tellg();
+       m_stream.seekg(0, std::ios_base::beg);
+       
+       char buffer[2];
+       m_stream.read(buffer, 2);
+       bool isSRecord = (buffer[0] == 'S' && isdigit(buffer[1]));
+       
+       m_stream.seekg(savePosition, std::ios_base::beg);
+       
+       return isSRecord;
+}
+
+//! Extract records one line at a time and hand them to the parseLine()
+//! method. Either CR, LF, or CRLF line endings are supported. The input
+//! stream is read until EOF.
+//! The parse() method must be called after the object has been constructed
+//! before any of the records will become accessible.
+//! \exception StSRecordParseException will be thrown if any error occurs while
+//!            parsing the input.
+void StSRecordFile::parse()
+{
+       // back to start of stream
+       m_stream.seekg(0, std::ios_base::beg);
+       
+       std::string thisLine;
+       
+       do {
+               char thisChar;
+               m_stream.get(thisChar);
+               
+               if (thisChar == '\r' || thisChar == '\n')
+               {
+                       // skip the LF in a CRLF
+                       if (thisChar == '\r' && m_stream.peek() == '\n')
+                               m_stream.ignore();
+                       
+                       // parse line if it's not empty
+                       if (!thisLine.empty())
+                       {
+                               parseLine(thisLine);
+                       
+                               // reset line
+                               thisLine.clear();
+                       }
+               }
+               else
+               {
+                       thisLine += thisChar;
+               }
+       } while (!m_stream.eof());
+}
+
+bool StSRecordFile::isHexDigit(char c)
+{
+       return (isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
+}
+
+int StSRecordFile::hexDigitToInt(char digit)
+{
+       if (isdigit(digit))
+               return digit - '0';
+       else if (digit >= 'a' && digit <= 'f')
+               return 10 + digit - 'a';
+       else if (digit >= 'A' && digit <= 'F')
+               return 10 + digit - 'A';
+       
+       // unknow char
+       return 0;
+}
+
+//! \exception StSRecordParseException is thrown if either of the nibble characters
+//!            is not a valid hex digit.
+int StSRecordFile::readHexByte(std::string & inString, int inIndex)
+{
+       char nibbleCharHi= inString[inIndex];
+       char nibbleCharLo = inString[inIndex + 1];
+       
+       // must be hex digits
+       if (!(isHexDigit(nibbleCharHi) && isHexDigit(nibbleCharLo)))
+    {
+               throw StSRecordParseException("invalid hex digit");
+    }
+       
+       return (hexDigitToInt(nibbleCharHi) << 4) | hexDigitToInt(nibbleCharLo);
+}
+
+//! \brief Parses individual S-records.
+//!
+//! Takes a single S-record line as input and appends a new SRecord struct
+//! to the m_records vector.
+//! \exception StSRecordParseException will be thrown if any error occurs while
+//!            parsing \a inLine.
+void StSRecordFile::parseLine(std::string & inLine)
+{
+       int checksum = 0;
+       SRecord newRecord;
+       memset(&newRecord, 0, sizeof(newRecord));
+       
+       // must start with "S" and be at least a certain length
+       if (inLine[0] != SRECORD_START_CHAR && inLine.length() >= SRECORD_MIN_LENGTH)
+    {
+        throw StSRecordParseException("invalid record length");
+    }
+
+       // parse type field
+       char typeChar = inLine[1];
+       if (!isdigit(typeChar))
+    {
+               throw StSRecordParseException("invalid S-record type");
+    }
+       newRecord.m_type = typeChar - '0';
+       
+       // parse count field
+       newRecord.m_count = readHexByte(inLine, 2);
+       checksum += newRecord.m_count;
+       
+       // verify the record length now that we know the count
+       if (inLine.length() != 4 + newRecord.m_count * 2)
+    {
+               throw StSRecordParseException("invalid record length");
+    }
+       
+       // get address length
+       int addressLength;      // len in bytes
+       bool hasData = false;
+       switch (newRecord.m_type)
+       {
+               case 0:     // contains header information
+                       addressLength = 2;
+                       hasData = true;
+                       break;
+               case 1:     // data record with 2-byte address
+                       addressLength = 2;
+                       hasData = true;
+                       break;
+               case 2:     // data record with 3-byte address
+                       addressLength = 3;
+                       hasData = true;
+                       break;
+               case 3:     // data record with 4-byte address
+                       addressLength = 4;
+                       hasData = true;
+                       break;
+               case 5:     // the 2-byte address field contains a count of all prior S1, S2, and S3 records
+                       addressLength = 2;
+                       break;
+               case 7:     // entry point record with 4-byte address
+                       addressLength = 4;
+                       break;
+               case 8:     // entry point record with 3-byte address
+                       addressLength = 3;
+                       break;
+               case 9:     // entry point record with 2-byte address
+                       addressLength = 2;
+                       break;
+               default:
+                       // unrecognized type
+                       //throw StSRecordParseException("unknown S-record type");
+            break;
+       }
+       
+       // read address
+       int address = 0;
+       int i;
+       for (i=0; i < addressLength; ++i)
+       {
+               int addressByte = readHexByte(inLine, SRECORD_ADDRESS_START_CHAR_INDEX + i * 2);
+               address = (address << 8) | addressByte;
+               checksum += addressByte;
+       }
+       newRecord.m_address = address;
+               
+       // read data
+       if (hasData)
+       {
+               int dataStartCharIndex = 4 + addressLength * 2;
+               int dataLength = newRecord.m_count - addressLength - 1; // total rem - addr - cksum (in bytes)
+               uint8_t * data = new uint8_t[dataLength];
+               
+               for (i=0; i < dataLength; ++i)
+               {
+                       int dataByte = readHexByte(inLine, dataStartCharIndex + i * 2);
+                       data[i] = dataByte;
+                       checksum += dataByte;
+               }
+               
+               newRecord.m_data = data;
+               newRecord.m_dataCount = dataLength;
+       }
+       
+       // read and compare checksum byte
+       checksum = (~checksum) & 0xff;  // low byte of one's complement of sum of other bytes
+       newRecord.m_checksum = readHexByte(inLine, (int)inLine.length() - 2);
+       if (checksum != newRecord.m_checksum)
+    {
+               throw StSRecordParseException("invalid checksum");
+    }
+       
+       // now save the new S-record
+       m_records.push_back(newRecord);
+}
diff --git a/tools/elftosb/common/StSRecordFile.h b/tools/elftosb/common/StSRecordFile.h
new file mode 100644 (file)
index 0000000..4340c6a
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * File:       StSRecordFile.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_StSRecordFile_h_)
+#define _StSRecordFile_h_
+
+//#include <stdint.h>
+#include "stdafx.h"
+#include <istream>
+#include <string>
+#include <vector>
+#include <stdexcept>
+
+enum {
+       //! The required first character of an S-record.
+       SRECORD_START_CHAR = 'S',
+       
+       //! The minimum length of a S-record. This is the type (2) + count (2) + addr (4) + cksum (2).
+       SRECORD_MIN_LENGTH = 10,
+       
+       //! Index of the first character of the address field.
+       SRECORD_ADDRESS_START_CHAR_INDEX = 4
+};
+
+/*!
+ * \brief S-record parser.
+ *
+ * This class takes an input stream and parses it as an S-record file. While
+ * the individual records that comprise the file are available for access, the
+ * class also provides a higher-level view of the contents. It processes the
+ * individual records and builds an image of what the memory touched by the
+ * file looks like. Then you can access the contiguous sections of memory.
+ */
+class StSRecordFile
+{
+public:
+       /*!
+        * Structure representing each individual line of the S-record input data.
+        */
+       struct SRecord
+       {
+               unsigned m_type;                //!< Record number type, such as 9 for "S9", 3 for "S3" and so on.
+               unsigned m_count;               //!< Number of character pairs (bytes) from address through checksum.
+               uint32_t m_address;                     //!< The address specified as part of the S-record.
+               unsigned m_dataCount;   //!< Number of bytes of data.
+               uint8_t * m_data;                       //!< Pointer to data, or NULL if no data for this record type.
+               uint8_t m_checksum;                     //!< The checksum byte present in the S-record.
+       };
+       
+       //! Iterator type.
+       typedef std::vector<SRecord>::const_iterator const_iterator;
+       
+public:
+       //! \brief Constructor.
+       StSRecordFile(std::istream & inStream);
+       
+       //! \brief Destructor.
+       virtual ~StSRecordFile();
+
+       //! \name File name
+       //@{
+       virtual void setName(const std::string & inName) { m_name = inName; }
+       virtual std::string getName() const { return m_name; }
+       //@}
+       
+       //! \name Parsing
+       //@{
+       //! \brief Determine if the file is an S-record file.
+       virtual bool isSRecordFile();
+       
+       //! \brief Parses the entire S-record input stream.
+       virtual void parse();
+       //@}
+       
+       //! \name Record access
+       //@{
+       //! \return the number of S-records that have been parsed from the input stream.
+       inline unsigned getRecordCount() const { return static_cast<unsigned>(m_records.size()); }
+       
+       //! \return iterator for 
+       inline const_iterator getBegin() const { return m_records.begin(); }
+       inline const_iterator getEnd() const { return m_records.end(); }
+       //@}
+       
+       //! \name Operators
+       //@{
+       inline const SRecord & operator [] (unsigned inIndex) { return m_records[inIndex]; }
+       //@}
+       
+protected:
+       std::istream& m_stream; //!< The input stream for the S-record data.
+       std::vector<SRecord> m_records; //!< Vector of S-records in the input data.
+
+    std::string m_name;                        //!< File name. (optional)
+
+       //! \name Parsing utilities
+       //@{
+       virtual void parseLine(std::string & inLine);
+       
+       bool isHexDigit(char c);
+       int hexDigitToInt(char digit);
+       int readHexByte(std::string & inString, int inIndex);
+       //@}
+};
+
+/*!
+ * \brief Simple exception thrown to indicate an error in the input SRecord data format.
+ */
+class StSRecordParseException : public std::runtime_error
+{
+public:
+    //! \brief Default constructor.
+    StSRecordParseException(const std::string & inMessage) : std::runtime_error(inMessage) {}
+};
+
+#endif // _StSRecordFile_h_
diff --git a/tools/elftosb/common/StringMatcher.h b/tools/elftosb/common/StringMatcher.h
new file mode 100644 (file)
index 0000000..e8074ff
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * File:       GlobSectionSelector.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_StringMatcher_h_)
+#define _StringMatcher_h_
+
+#include <string>
+
+namespace elftosb
+{
+
+/*!
+ * \brief Abstract interface class used to select strings by name.
+ */
+class StringMatcher
+{
+public:
+       //! \brief Performs a single string match test against testValue.
+       //!
+       //! \retval true The \a testValue argument matches.
+       //! \retval false No match was made against the argument.
+       virtual bool match(const std::string & testValue)=0;
+};
+
+/*!
+ * \brief String matcher subclass that matches all test strings.
+ */
+class WildcardMatcher : public StringMatcher
+{
+public:
+       //! \brief Always returns true, indicating a positive match.
+       virtual bool match(const std::string & testValue) { return true; }
+};
+
+/*!
+ * \brief Simple string matcher that compares against a fixed value.
+ */
+class FixedMatcher : public StringMatcher
+{
+public:
+       //! \brief Constructor. Sets the string to compare against to be \a fixedValue.
+       FixedMatcher(const std::string & fixedValue) : m_value(fixedValue) {}
+       
+       //! \brief Returns whether \a testValue is the same as the value passed to the constructor.
+       //!
+       //! \retval true The \a testValue argument matches the fixed compare value.
+       //! \retval false The argument is not the same as the compare value.
+       virtual bool match(const std::string & testValue)
+       {
+               return testValue == m_value;
+       }
+
+protected:
+       const std::string & m_value;    //!< The section name to look for.
+};
+
+}; // namespace elftosb
+
+#endif // _StringMatcher_h_
diff --git a/tools/elftosb/common/Value.cpp b/tools/elftosb/common/Value.cpp
new file mode 100644 (file)
index 0000000..5a6a034
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * File:       Value.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "Value.h"
+
+using namespace elftosb;
+
+//! Returns a varying size depending on the word size attribute.
+//!
+size_t SizedIntegerValue::getSize() const
+{
+       switch (m_size)
+       {
+               case kWordSize:
+                       return sizeof(uint32_t);
+               case kHalfWordSize:
+                       return sizeof(uint16_t);
+               case kByteSize:
+                       return sizeof(uint8_t);
+       }
+       return kWordSize;
+}
+
+//! The resulting mask can be used to truncate the integer value to be
+//! certain it doesn't extend beyond the associated word size.
+uint32_t SizedIntegerValue::getWordSizeMask() const
+{
+       switch (m_size)
+       {
+               case kWordSize:
+                       return 0xffffffff;
+               case kHalfWordSize:
+                       return 0x0000ffff;
+               case kByteSize:
+                       return 0x000000ff;
+       }
+       return 0;
+}
+
diff --git a/tools/elftosb/common/Value.h b/tools/elftosb/common/Value.h
new file mode 100644 (file)
index 0000000..8a676d5
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * File:       Value.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_Value_h_)
+#define _Value_h_
+
+#include "stdafx.h"
+#include <string>
+#include "int_size.h"
+#include "Blob.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Abstract base class for values of arbitrary types.
+ */
+class Value
+{
+public:
+       Value() {}
+       virtual ~Value() {}
+       
+       virtual std::string getTypeName() const = 0;
+       virtual size_t getSize() const = 0;
+};
+
+/*!
+ * \brief 32-bit signed integer value.
+ */
+class IntegerValue : public Value
+{
+public:
+       IntegerValue() : m_value(0) {}
+       IntegerValue(uint32_t value) : m_value(value) {}
+       IntegerValue(const IntegerValue & other) : m_value(other.m_value) {}
+       
+       virtual std::string getTypeName() const { return "integer"; }
+       virtual size_t getSize() const { return sizeof(m_value); }
+       
+       inline uint32_t getValue() const { return m_value; }
+       
+       inline operator uint32_t () const { return m_value; }
+       
+       inline IntegerValue & operator = (uint32_t value) { m_value = value; return *this; }
+
+protected:
+       uint32_t m_value;       //!< The integer value.
+};
+
+/*!
+ * \brief Adds a word size attribute to IntegerValue.
+ *
+ * The word size really only acts as an attribute that is carried along
+ * with the integer value. It doesn't affect the actual value at all.
+ * However, you can use the getWordSizeMask() method to mask off bits
+ * that should not be there.
+ *
+ * The word size defaults to a 32-bit word.
+ */
+class SizedIntegerValue : public IntegerValue
+{
+public:
+       SizedIntegerValue() : IntegerValue(), m_size(kWordSize) {}
+       SizedIntegerValue(uint32_t value, int_size_t size=kWordSize) : IntegerValue(value), m_size(size) {}
+       SizedIntegerValue(uint16_t value) : IntegerValue(value), m_size(kHalfWordSize) {}
+       SizedIntegerValue(uint8_t value) : IntegerValue(value), m_size(kByteSize) {}
+       SizedIntegerValue(const SizedIntegerValue & other) : IntegerValue(other), m_size(other.m_size) {}
+       
+       virtual std::string getTypeName() const { return "sized integer"; }
+       virtual size_t getSize() const;
+       
+       inline int_size_t getWordSize() const { return m_size; }
+       inline void setWordSize(int_size_t size) { m_size = size; }
+       
+       //! \brief Returns a 32-bit mask value dependant on the word size attribute.
+       uint32_t getWordSizeMask() const;
+       
+       //! \name Assignment operators
+       //! These operators set the word size as well as the integer value.
+       //@{
+       SizedIntegerValue & operator = (uint8_t value) { m_value = value; m_size = kByteSize; return *this; }
+       SizedIntegerValue & operator = (uint16_t value) { m_value = value; m_size = kHalfWordSize; return *this; }
+       SizedIntegerValue & operator = (uint32_t value) { m_value = value; m_size = kWordSize; return *this; }
+       //@}
+       
+protected:
+       int_size_t m_size;      //!< Size of the integer.
+};
+
+/*!
+ * \brief String value.
+ *
+ * Simply wraps the STL std::string class.
+ */
+class StringValue : public Value
+{
+public:
+       StringValue() : m_value() {}
+       StringValue(const std::string & value) : m_value(value) {}
+       StringValue(const std::string * value) : m_value(*value) {}
+       StringValue(const StringValue & other) : m_value(other.m_value) {}
+       
+       virtual std::string getTypeName() const { return "string"; }
+       virtual size_t getSize() const { return m_value.size(); }
+       
+       operator const char * () const { return m_value.c_str(); }
+       operator const std::string & () const { return m_value; }
+       operator std::string & () { return m_value; }
+       operator const std::string * () { return &m_value; }
+       operator std::string * () { return &m_value; }
+       
+       StringValue & operator = (const StringValue & other) { m_value = other.m_value; return *this; }
+       StringValue & operator = (const std::string & value) { m_value = value; return *this; }
+       StringValue & operator = (const char * value) { m_value = value; return *this; }
+       
+protected:
+       std::string m_value;
+};
+
+/*!
+ * \brief Binary object value of arbitrary size.
+ */
+class BinaryValue : public Value, public Blob
+{
+public:
+       BinaryValue() : Value(), Blob() {}
+       
+       virtual std::string getTypeName() const { return "binary"; }
+       virtual size_t getSize() const { return getLength(); }
+};
+
+}; // namespace elftosb
+
+#endif // _Value_h_
diff --git a/tools/elftosb/common/Version.cpp b/tools/elftosb/common/Version.cpp
new file mode 100644 (file)
index 0000000..5d40d67
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * File:       Version.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "Version.h"
+#include "EndianUtilities.h"
+
+using namespace elftosb;
+
+/*!
+ * Parses a string in the form "xxx.xxx.xxx" (where x is a digit) into
+ * three version fields for major, minor, and revision. The output is
+ * right aligned BCD in host-natural byte order.
+ *
+ * \param versionString String containing the version.
+ */
+void version_t::set(const std::string & versionString)
+{
+       size_t length = versionString.size();
+       unsigned version = 0;
+       unsigned index = 0;
+       
+       typedef enum {
+               kVersionStateNone,
+               kVersionStateMajor,
+               kVersionStateMinor,
+               kVersionStateRevision
+       } VersionParseState;
+       
+       // set initial versions to 0s
+       m_major = 0;
+       m_minor = 0;
+       m_revision = 0;
+       
+       VersionParseState parseState = kVersionStateNone;
+       bool done = false;
+       for (; index < length && !done; ++index)
+       {
+               char c = versionString[index];
+               
+               if (isdigit(c))
+               {
+                       switch (parseState)
+                       {
+                               case kVersionStateNone:
+                                       parseState = kVersionStateMajor;
+                                       version = c - '0';
+                                       break;
+                               case kVersionStateMajor:
+                               case kVersionStateMinor:
+                               case kVersionStateRevision:
+                                       version = (version << 4) | (c - '0');
+                                       break;
+                       }
+               }
+               else if (c == '.')
+               {
+                       switch (parseState)
+                       {
+                               case kVersionStateNone:
+                                       parseState = kVersionStateNone;
+                                       break;
+                               case kVersionStateMajor:
+                                       m_major = version;
+                                       version = 0;
+                                       parseState = kVersionStateMinor;
+                                       break;
+                               case kVersionStateMinor:
+                                       m_minor = version;
+                                       version = 0;
+                                       parseState = kVersionStateRevision;
+                                       break;
+                               case kVersionStateRevision:
+                                       m_revision = version;
+                                       version = 0;
+                                       done = true;
+                                       break;
+                       }
+               }
+               else
+               {
+                       switch (parseState)
+                       {
+                               case kVersionStateNone:
+                                       parseState = kVersionStateNone;
+                                       break;
+                               case kVersionStateMajor:
+                                       m_major = version;
+                                       done = true;
+                                       break;
+                               case kVersionStateMinor:
+                                       m_minor = version;
+                                       done = true;
+                                       break;
+                               case kVersionStateRevision:
+                                       m_revision = version;
+                                       done = true;
+                                       break;
+                       }
+               }
+       }
+       
+       switch (parseState)
+       {
+               case kVersionStateMajor:
+                       m_major = version;
+                       break;
+               case kVersionStateMinor:
+                       m_minor = version;
+                       break;
+               case kVersionStateRevision:
+                       m_revision = version;
+                       break;
+               default:
+                       // do nothing
+                       break;
+       }
+}
+
+//! \brief Converts host endian BCD version values to the equivalent big-endian BCD values.
+//!
+//! The output is a half-word. And BCD is inherently big-endian, or byte ordered, if
+//! you prefer to think of it that way. So for little endian systems, we need to convert
+//! the output half-word in reverse byte order. When it is written to disk or a
+//! buffer it will come out big endian.
+//!
+//! For example:
+//!     - The input is BCD in host endian format, so 0x1234. Written to a file, this would
+//!       come out as 0x34 0x12, reverse of what we want.
+//!     - The desired BCD output is the two bytes 0x12 0x34.
+//!     - So the function's uint16_t result must be 0x3412 on a little-endian host.
+//!
+//! On big endian hosts, we don't have to worry about byte swapping.
+void version_t::fixByteOrder()
+{
+       m_major = ENDIAN_HOST_TO_BIG_U16(m_major);
+       m_minor = ENDIAN_HOST_TO_BIG_U16(m_minor);
+       m_revision = ENDIAN_HOST_TO_BIG_U16(m_revision);
+}
+
diff --git a/tools/elftosb/common/Version.h b/tools/elftosb/common/Version.h
new file mode 100644 (file)
index 0000000..9533586
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * File:       Version.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_Version_h_)
+#define _Version_h_
+
+#include <string>
+#include "stdafx.h"
+
+namespace elftosb
+{
+
+//! Same version struct used for 3600 boot image.
+struct version_t
+{
+       uint16_t m_major;
+       uint16_t m_pad0;
+       uint16_t m_minor;
+       uint16_t m_pad1;
+       uint16_t m_revision;
+       uint16_t m_pad2;
+       
+       version_t()
+       :       m_major(0x999), m_pad0(0), m_minor(0x999), m_pad1(0), m_revision(0x999), m_pad2(0)
+       {
+       }
+       
+       version_t(uint16_t maj, uint16_t min, uint16_t rev)
+       :       m_major(maj), m_pad0(0), m_minor(min), m_pad1(0), m_revision(rev), m_pad2(0)
+       {
+       }
+       
+       version_t(const std::string & versionString)
+       :       m_major(0x999), m_pad0(0), m_minor(0x999), m_pad1(0), m_revision(0x999), m_pad2(0)
+       {
+               set(versionString);
+       }
+       
+       //! \brief Sets the version by parsing a string.
+       void set(const std::string & versionString);
+
+       //! \brief
+       void fixByteOrder();
+};
+
+}; // namespace elftosb
+
+#endif // _Version_h_
diff --git a/tools/elftosb/common/crc.cpp b/tools/elftosb/common/crc.cpp
new file mode 100644 (file)
index 0000000..8c32819
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * File:       crc.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "crc.h"
+
+//! Table of CRC-32's of all single byte values. The values in
+//! this table are those used in the Ethernet CRC algorithm.
+const uint32_t CRC32::m_tab[] = {
+//#ifdef __LITTLE_ENDIAN__
+    0x00000000,
+    0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+    0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
+    0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+    0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
+    0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
+    0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
+    0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+    0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
+    0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
+    0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
+    0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+    0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
+    0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
+    0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
+    0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+    0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
+    0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
+    0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
+    0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+    0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
+    0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
+    0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
+    0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+    0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
+    0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
+    0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
+    0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+    0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
+    0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
+    0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
+    0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+    0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
+    0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
+    0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
+    0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+    0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
+    0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
+    0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
+    0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+    0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
+    0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
+    0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
+    0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+    0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
+    0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
+    0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
+    0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+    0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
+    0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
+    0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
+    0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+//#else
+//    0x00000000,
+//    0xb71dc104, 0x6e3b8209, 0xd926430d, 0xdc760413, 0x6b6bc517,
+//    0xb24d861a, 0x0550471e, 0xb8ed0826, 0x0ff0c922, 0xd6d68a2f,
+//    0x61cb4b2b, 0x649b0c35, 0xd386cd31, 0x0aa08e3c, 0xbdbd4f38,
+//    0x70db114c, 0xc7c6d048, 0x1ee09345, 0xa9fd5241, 0xacad155f,
+//    0x1bb0d45b, 0xc2969756, 0x758b5652, 0xc836196a, 0x7f2bd86e,
+//    0xa60d9b63, 0x11105a67, 0x14401d79, 0xa35ddc7d, 0x7a7b9f70,
+//    0xcd665e74, 0xe0b62398, 0x57abe29c, 0x8e8da191, 0x39906095,
+//    0x3cc0278b, 0x8bdde68f, 0x52fba582, 0xe5e66486, 0x585b2bbe,
+//    0xef46eaba, 0x3660a9b7, 0x817d68b3, 0x842d2fad, 0x3330eea9,
+//    0xea16ada4, 0x5d0b6ca0, 0x906d32d4, 0x2770f3d0, 0xfe56b0dd,
+//    0x494b71d9, 0x4c1b36c7, 0xfb06f7c3, 0x2220b4ce, 0x953d75ca,
+//    0x28803af2, 0x9f9dfbf6, 0x46bbb8fb, 0xf1a679ff, 0xf4f63ee1,
+//    0x43ebffe5, 0x9acdbce8, 0x2dd07dec, 0x77708634, 0xc06d4730,
+//    0x194b043d, 0xae56c539, 0xab068227, 0x1c1b4323, 0xc53d002e,
+//    0x7220c12a, 0xcf9d8e12, 0x78804f16, 0xa1a60c1b, 0x16bbcd1f,
+//    0x13eb8a01, 0xa4f64b05, 0x7dd00808, 0xcacdc90c, 0x07ab9778,
+//    0xb0b6567c, 0x69901571, 0xde8dd475, 0xdbdd936b, 0x6cc0526f,
+//    0xb5e61162, 0x02fbd066, 0xbf469f5e, 0x085b5e5a, 0xd17d1d57,
+//    0x6660dc53, 0x63309b4d, 0xd42d5a49, 0x0d0b1944, 0xba16d840,
+//    0x97c6a5ac, 0x20db64a8, 0xf9fd27a5, 0x4ee0e6a1, 0x4bb0a1bf,
+//    0xfcad60bb, 0x258b23b6, 0x9296e2b2, 0x2f2bad8a, 0x98366c8e,
+//    0x41102f83, 0xf60dee87, 0xf35da999, 0x4440689d, 0x9d662b90,
+//    0x2a7bea94, 0xe71db4e0, 0x500075e4, 0x892636e9, 0x3e3bf7ed,
+//    0x3b6bb0f3, 0x8c7671f7, 0x555032fa, 0xe24df3fe, 0x5ff0bcc6,
+//    0xe8ed7dc2, 0x31cb3ecf, 0x86d6ffcb, 0x8386b8d5, 0x349b79d1,
+//    0xedbd3adc, 0x5aa0fbd8, 0xeee00c69, 0x59fdcd6d, 0x80db8e60,
+//    0x37c64f64, 0x3296087a, 0x858bc97e, 0x5cad8a73, 0xebb04b77,
+//    0x560d044f, 0xe110c54b, 0x38368646, 0x8f2b4742, 0x8a7b005c,
+//    0x3d66c158, 0xe4408255, 0x535d4351, 0x9e3b1d25, 0x2926dc21,
+//    0xf0009f2c, 0x471d5e28, 0x424d1936, 0xf550d832, 0x2c769b3f,
+//    0x9b6b5a3b, 0x26d61503, 0x91cbd407, 0x48ed970a, 0xfff0560e,
+//    0xfaa01110, 0x4dbdd014, 0x949b9319, 0x2386521d, 0x0e562ff1,
+//    0xb94beef5, 0x606dadf8, 0xd7706cfc, 0xd2202be2, 0x653deae6,
+//    0xbc1ba9eb, 0x0b0668ef, 0xb6bb27d7, 0x01a6e6d3, 0xd880a5de,
+//    0x6f9d64da, 0x6acd23c4, 0xddd0e2c0, 0x04f6a1cd, 0xb3eb60c9,
+//    0x7e8d3ebd, 0xc990ffb9, 0x10b6bcb4, 0xa7ab7db0, 0xa2fb3aae,
+//    0x15e6fbaa, 0xccc0b8a7, 0x7bdd79a3, 0xc660369b, 0x717df79f,
+//    0xa85bb492, 0x1f467596, 0x1a163288, 0xad0bf38c, 0x742db081,
+//    0xc3307185, 0x99908a5d, 0x2e8d4b59, 0xf7ab0854, 0x40b6c950,
+//    0x45e68e4e, 0xf2fb4f4a, 0x2bdd0c47, 0x9cc0cd43, 0x217d827b,
+//    0x9660437f, 0x4f460072, 0xf85bc176, 0xfd0b8668, 0x4a16476c,
+//    0x93300461, 0x242dc565, 0xe94b9b11, 0x5e565a15, 0x87701918,
+//    0x306dd81c, 0x353d9f02, 0x82205e06, 0x5b061d0b, 0xec1bdc0f,
+//    0x51a69337, 0xe6bb5233, 0x3f9d113e, 0x8880d03a, 0x8dd09724,
+//    0x3acd5620, 0xe3eb152d, 0x54f6d429, 0x7926a9c5, 0xce3b68c1,
+//    0x171d2bcc, 0xa000eac8, 0xa550add6, 0x124d6cd2, 0xcb6b2fdf,
+//    0x7c76eedb, 0xc1cba1e3, 0x76d660e7, 0xaff023ea, 0x18ede2ee,
+//    0x1dbda5f0, 0xaaa064f4, 0x738627f9, 0xc49be6fd, 0x09fdb889,
+//    0xbee0798d, 0x67c63a80, 0xd0dbfb84, 0xd58bbc9a, 0x62967d9e,
+//    0xbbb03e93, 0x0cadff97, 0xb110b0af, 0x060d71ab, 0xdf2b32a6,
+//    0x6836f3a2, 0x6d66b4bc, 0xda7b75b8, 0x035d36b5, 0xb440f7b1
+//#endif // __LITTLE_ENDIAN__
+
+// This is the original table that came with this source.
+//#ifdef __LITTLE_ENDIAN__
+//     0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+//     0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+//     0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+//     0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+//     0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+//     0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+//     0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+//     0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+//     0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+//     0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+//     0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+//     0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+//     0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+//     0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+//     0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+//     0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+//     0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+//     0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+//     0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+//     0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+//     0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+//     0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+//     0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+//     0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+//     0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+//     0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+//     0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+//     0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+//     0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+//     0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+//     0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+//     0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+//     0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+//     0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+//     0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+//     0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+//     0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+//     0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+//     0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+//     0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+//     0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+//     0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+//     0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+//     0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+//     0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+//     0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+//     0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+//     0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+//     0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+//     0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+//     0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+//     0x2d02ef8dL
+//#else
+//     0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L,
+//     0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L,
+//     0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L,
+//     0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L,
+//     0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L,
+//     0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L,
+//     0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L,
+//     0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L,
+//     0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L,
+//     0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L,
+//     0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL,
+//     0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L,
+//     0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L,
+//     0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L,
+//     0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L,
+//     0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L,
+//     0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL,
+//     0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L,
+//     0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL,
+//     0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L,
+//     0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L,
+//     0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L,
+//     0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL,
+//     0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL,
+//     0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L,
+//     0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL,
+//     0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L,
+//     0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL,
+//     0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L,
+//     0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L,
+//     0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L,
+//     0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L,
+//     0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L,
+//     0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL,
+//     0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L,
+//     0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L,
+//     0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L,
+//     0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L,
+//     0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L,
+//     0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L,
+//     0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L,
+//     0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L,
+//     0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL,
+//     0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L,
+//     0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L,
+//     0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L,
+//     0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L,
+//     0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L,
+//     0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL,
+//     0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L,
+//     0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL,
+//     0x8def022dL
+//#endif
+};
+
+CRC32::CRC32()
+{
+       reset();
+}
+
+void CRC32::update(const uint8_t * s, unsigned n)
+{
+       uint32_t crc = m_crc;
+    m_count += n;
+    
+    while (n--)
+    {
+        uint8_t c = *s++ & 0xff;
+        crc = (crc << 8) ^ m_tab[(crc >> 24) ^ c];
+    }
+       
+//     for(; !((reinterpret_cast<uint32_t>(s) & 0x3) == 0) && n > 0; n--)
+//     {
+//             crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc);
+//     }
+//
+//     while (n >= 4)
+//     {
+//             crc ^= *(const uint32_t *)s;
+//             crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
+//             crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
+//             crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
+//             crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc);
+//             n -= 4;
+//             s += 4;
+//     }
+//
+//     while (n--)
+//     {
+//             crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc);
+//     }
+
+       m_crc = crc;
+}
+
+void CRC32::truncatedFinal(uint8_t * hash, unsigned size)
+{
+    // pad with zeroes
+    if (m_count % 4)
+    {
+        unsigned i;
+        for (i = m_count % 4; i < 4; i++) {
+            m_crc = (m_crc << 8) ^ m_tab[(m_crc >> 24) ^ 0];
+        }
+    }
+    
+//     m_crc ^= CRC32_NEGL;
+       
+       unsigned i;
+       for (i=0; i<size; i++)
+       {
+               hash[i] = getCrcByte(i);
+       }
+
+       reset();
+}
+
diff --git a/tools/elftosb/common/crc.h b/tools/elftosb/common/crc.h
new file mode 100644 (file)
index 0000000..d6d0b7a
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * File:       crc.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_crc_h_)
+#define CRYPTOPP_CRC32_H
+
+#include "stdafx.h"
+
+const uint32_t CRC32_NEGL = 0xffffffffL;
+
+#ifdef __LITTLE_ENDIAN__
+       #define CRC32_INDEX(c) (c & 0xff)
+       #define CRC32_SHIFTED(c) (c >> 8)
+#else
+       #define CRC32_INDEX(c) (c >> 24)
+       #define CRC32_SHIFTED(c) (c << 8)
+#endif
+
+//! CRC Checksum Calculation
+class CRC32
+{
+public:
+       enum
+       {
+               DIGESTSIZE = 4
+       };
+       
+       CRC32();
+       
+       void update(const uint8_t * input, unsigned length);
+       
+       void truncatedFinal(uint8_t * hash, unsigned size);
+
+       void updateByte(uint8_t b) { m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc); }
+       uint8_t getCrcByte(unsigned i) const { return ((uint8_t *)&(m_crc))[i]; }
+
+private:
+       void reset() { m_crc = CRC32_NEGL; m_count = 0; }
+       
+       static const uint32_t m_tab[256];
+       uint32_t m_crc;
+    unsigned m_count;
+};
+
+#endif // _crc_h_
diff --git a/tools/elftosb/common/format_string.cpp b/tools/elftosb/common/format_string.cpp
new file mode 100644 (file)
index 0000000..3a26d0c
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * File:       format_string.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "format_string.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdexcept>
+#include <string.h>
+#include <stdlib.h>
+//! Size of the temporary buffer to hold the formatted output string.
+#define WIN32_FMT_BUF_LEN (512)
+
+/*!
+ * \brief Simple template class to free a pointer.
+ */
+template <typename T>
+class free_ptr
+{
+public:
+       //! \brief Constructor.
+       free_ptr(T ptr)
+       :       m_p(ptr)
+       {
+       }
+       
+       //! \brief Destructor.
+       ~free_ptr()
+       {
+               if (m_p)
+               {
+                       free(m_p);
+               }
+       }
+
+protected:
+       T m_p;  //!< The value to free.
+};
+
+//! The purpose of this function to provide a convenient way of generating formatted
+//! STL strings inline. This is especially useful when throwing exceptions that take
+//! a std::string for a message. The length of the formatted output string is limited
+//! only by memory. Memory temporarily allocated for the output string is disposed of
+//! before returning.
+//!
+//! Example usage:
+//! \code
+//!            throw std::runtime_error(format_string("error on line %d", line));
+//! \endcode
+//!
+//! \param fmt Format string using printf-style format markers.
+//! \return An STL string object of the formatted output.
+std::string format_string(const char * fmt, ...)
+{
+       char * buf = 0;
+       va_list vargs;
+       va_start(vargs, fmt);
+       int result = -1;
+#if WIN32
+    buf = (char *)malloc(WIN32_FMT_BUF_LEN);
+    if (buf)
+    {
+        result = _vsnprintf(buf, WIN32_FMT_BUF_LEN, fmt, vargs);
+    }
+#else // WIN32
+       result = vasprintf(&buf, fmt, vargs);
+#endif // WIN32
+       va_end(vargs);
+       if (result != -1 && buf)
+       {
+               free_ptr<char *> freebuf(buf);
+               return std::string(buf);
+       }
+       return "";
+}
+
diff --git a/tools/elftosb/common/format_string.h b/tools/elftosb/common/format_string.h
new file mode 100644 (file)
index 0000000..a879d4e
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * File:       format_string.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_format_string_h_)
+#define _format_string_h_
+
+#include <string>
+#include <stdexcept>
+
+/*!
+ * \brief Returns a formatted STL string using printf format strings.
+ */
+std::string format_string(const char * fmt, ...);
+
+
+#endif // _format_string_h_
+
diff --git a/tools/elftosb/common/int_size.h b/tools/elftosb/common/int_size.h
new file mode 100644 (file)
index 0000000..cf66d68
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * File:       int_size.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_int_size_h_)
+#define _int_size_h_
+
+namespace elftosb
+{
+
+//! Supported sizes of integers.
+typedef enum {
+       kWordSize,              //!< 32-bit word.
+       kHalfWordSize,  //!< 16-bit half word.
+       kByteSize               //!< 8-bit byte.
+} int_size_t;
+
+}; // namespace elftosb
+
+#endif // _int_size_h_
diff --git a/tools/elftosb/common/options.cpp b/tools/elftosb/common/options.cpp
new file mode 100644 (file)
index 0000000..9f12aa6
--- /dev/null
@@ -0,0 +1,1140 @@
+// ****************************************************************************
+// ^FILE: options.c - implement the functions defined in <options.h>
+//
+// ^HISTORY:
+//    01/16/92 Brad Appleton   <bradapp@enteract.com>  Created
+//
+//    03/23/93 Brad Appleton   <bradapp@enteract.com>
+//    - Added OptIstreamIter class
+//
+//    10/08/93 Brad Appleton   <bradapp@enteract.com>
+//    - Added "hidden" options
+//
+//    02/08/94 Brad Appleton   <bradapp@enteract.com>
+//    - Added "OptionSpec" class
+//    - Permitted use of stdio instead of iostreams via #ifdef USE_STDIO
+//
+//    03/08/94 Brad Appleton   <bradapp@enteract.com>
+//    - completed support for USE_STDIO
+//    - added #ifdef NO_USAGE for people who always want to print their own
+//    - Fixed stupid NULL pointer error in OptionsSpec class
+//
+//    07/31/97 Brad Appleton   <bradapp@enteract.com>
+//    - Added PARSE_POS control flag and POSITIONAL return value.
+// ^^**************************************************************************
+
+// #include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "options.h"
+
+using namespace std;
+
+extern "C" {
+   void  exit(int);
+}
+
+static const char ident[] = "@(#)Options  1.05" ;
+
+   // I need a portable version of "tolower" that does NOT modify
+   // non-uppercase characters.
+   //
+#define  TOLOWER(c)  (isupper(c) ? tolower(c) : c)
+
+   // Use this to shut the compiler up about NULL strings
+#define  NULLSTR  (char *)NULL
+
+// ******************************************************** insertion operators
+
+  // If you are using <stdio.h> then you need this stuff!
+  // If you are using <iostream.h> then #ifdef this stuff out
+  //
+
+
+#ifdef  USE_STDIO
+
+   // Implement just enough of ostream to get this file to compile
+   //
+
+static const char endl = '\n' ;
+
+class  ostream {
+public:
+   ostream(FILE * fileptr) : fp(fileptr) {}
+
+   ostream &
+   operator<<(char ch);
+
+   ostream &
+   operator<<(const char * str);
+
+   ostream &
+   write(const char * buf, unsigned bufsize);
+
+private:
+   FILE * fp;
+} ;
+
+ostream &
+ostream::operator<<(char ch) {
+   fputc(ch, fp);
+   return *this;
+}
+
+ostream &
+ostream::operator<<(const char * str) {
+   fputs(str, fp);
+   return *this;
+}
+
+ostream &
+ostream::write(const char * buf, unsigned ) {
+   fputs(buf, fp);
+   return *this;
+}
+
+static  ostream  cerr(stderr);
+static  ostream  cout(stdout);
+
+#endif  /* USE_STDIO */
+
+// ************************************************************** OptIter
+
+OptIter::~OptIter(void) {}
+
+const char *
+OptIter::operator()(void)  {
+   const char * elt = curr();
+   (void) next();
+   return  elt;
+}
+
+// ************************************************************** OptIterRwd
+
+OptIterRwd::OptIterRwd(void) {}
+
+OptIterRwd::~OptIterRwd(void) {}
+
+// ************************************************************** OptArgvIter
+
+OptArgvIter::~OptArgvIter(void) {}
+
+const char *
+OptArgvIter::curr(void) {
+   return ((ndx == ac) || (av[ndx] == NULL)) ? NULLSTR : av[ndx];
+}
+
+void
+OptArgvIter::next(void) {
+   if ((ndx != ac) && av[ndx]) ++ndx;
+}
+
+const char *
+OptArgvIter::operator()(void) {
+   return ((ndx == ac) || (av[ndx] == NULL)) ? NULLSTR : av[ndx++];
+}
+
+void
+OptArgvIter::rewind(void) { ndx = 0; }
+
+// ************************************************************** OptStrTokIter
+
+static const char WHITESPACE[] = " \t\n\r\v\f" ;
+const char * OptStrTokIter::default_delims = WHITESPACE ;
+
+OptStrTokIter::OptStrTokIter(const char * tokens, const char * delimiters)
+   : len(unsigned(strlen(tokens))), str(tokens), seps(delimiters),
+     cur(NULLSTR), tokstr(NULLSTR)
+{
+   if (seps == NULL)  seps = default_delims;
+   tokstr = new char[len + 1];
+   (void) ::strcpy(tokstr, str);
+   cur = ::strtok(tokstr, seps);
+}
+
+
+OptStrTokIter::~OptStrTokIter(void) { delete [] tokstr; }
+
+const char *
+OptStrTokIter::curr(void) { return cur; }
+
+void
+OptStrTokIter::next(void) { if (cur) cur = ::strtok(NULL, seps); }
+
+const char *
+OptStrTokIter::operator()(void) {
+   const char * elt = cur;
+   if (cur) cur = ::strtok(NULL, seps);
+   return  elt;
+}
+
+void
+OptStrTokIter::rewind(void) {
+   (void) ::strcpy(tokstr, str);
+   cur = ::strtok(tokstr, seps);
+}
+
+// ************************************************************* OptIstreamIter
+
+#ifdef vms
+   enum { c_COMMENT = '!' } ;
+#else
+   enum { c_COMMENT = '#' } ;
+#endif
+
+const unsigned  OptIstreamIter::MAX_LINE_LEN = 1024 ;
+
+   // Constructor
+OptIstreamIter::OptIstreamIter(istream & input) : is(input), tok_iter(NULL)
+{
+#ifdef  USE_STDIO
+   fprintf(stderr, "%s: Can't use OptIstreamIter class:\n",
+                   "OptIstreamIter::OptIstreamIter");
+   fprintf(stderr, "\tOptions(3C++) was compiled with USE_STDIO #defined.\n");
+   exit(-1);
+#endif  /* USE_STDIO */
+}
+
+   // Destructor
+OptIstreamIter::~OptIstreamIter(void) {
+   delete  tok_iter;
+}
+
+const char *
+OptIstreamIter::curr(void) {
+#ifdef  USE_STDIO
+   return  NULLSTR;
+#else
+   const char * result = NULLSTR;
+   if (tok_iter)  result = tok_iter->curr();
+   if (result)  return  result;
+   fill();
+   return (! is) ? NULLSTR : tok_iter->curr();
+#endif  /* USE_STDIO */
+}
+
+void
+OptIstreamIter::next(void) {
+#ifdef  USE_STDIO
+   return;
+#else
+   const char * result = NULLSTR;
+   if (tok_iter)  result = tok_iter->operator()();
+   if (result)  return;
+   fill();
+   if (! is) tok_iter->next();
+#endif  /* USE_STDIO */
+}
+
+const char *
+OptIstreamIter::operator()(void) {
+#ifdef  USE_STDIO
+   return  NULLSTR;
+#else
+   const char * result = NULLSTR;
+   if (tok_iter)  result = tok_iter->operator()();
+   if (result)  return  result;
+   fill();
+   return (! is) ? NULLSTR : tok_iter->operator()();
+#endif  /* USE_STDIO */
+}
+
+   // What we do is this: for each line of text in the istream, we use
+   // a OptStrTokIter to iterate over each token on the line.
+   //
+   // If the first non-white character on a line is c_COMMENT, then we
+   // consider the line to be a comment and we ignore it.
+   //
+void
+OptIstreamIter::fill(void) {
+#ifdef USE_STDIO
+   return;
+#else
+   char buf[OptIstreamIter::MAX_LINE_LEN];
+   do {
+      *buf = '\0';
+      is.getline(buf, sizeof(buf));
+      char * ptr = buf;
+      while (isspace(*ptr)) ++ptr;
+      if (*ptr && (*ptr != c_COMMENT)) {
+         delete  tok_iter;
+         tok_iter = new OptStrTokIter(ptr);
+         return;
+      }
+   } while (is);
+#endif  /* USE_STDIO */
+}
+
+// **************************************************** Options class utilities
+
+   // Is this option-char null?
+inline static int
+isNullOpt(char optchar) {
+   return  ((! optchar) || isspace(optchar) || (! isprint(optchar)));
+}
+   
+   // Check for explicit "end-of-options"
+inline static int
+isEndOpts(const char * token) {
+   return ((token == NULL) || (! ::strcmp(token, "--"))) ;
+}
+
+   // See if an argument is an option
+inline static int
+isOption(unsigned  flags, const char * arg) {
+   return  (((*arg != '\0') || (arg[1] != '\0')) &&
+            ((*arg == '-')  || ((flags & Options::PLUS) && (*arg == '+')))) ;
+}
+
+   // See if we should be parsing only options or if we also need to
+   // parse positional arguments
+inline static int
+isOptsOnly(unsigned  flags) {
+   return  (flags & Options::PARSE_POS) ? 0 : 1;
+}
+
+   // return values for a keyword matching function
+enum kwdmatch_t { NO_MATCH, PARTIAL_MATCH, EXACT_MATCH } ;
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: kwdmatch - match a keyword
+//
+// ^SYNOPSIS:
+//    static kwdmatch_t kwdmatch(src, attempt, len)
+//
+// ^PARAMETERS:
+//    char * src -- the actual keyword to match
+//    char * attempt -- the possible keyword to compare against "src"
+//    int len -- number of character of "attempt" to consider
+//               (if 0 then we should use all of "attempt")
+//
+// ^DESCRIPTION:
+//    See if "attempt" matches some prefix of "src" (case insensitive).
+//
+// ^REQUIREMENTS:
+//    - attempt should be non-NULL and non-empty
+//
+// ^SIDE-EFFECTS:
+//    None.
+//
+// ^RETURN-VALUE:
+//    An enumeration value of type kwdmatch_t corresponding to whether
+//    We had an exact match, a partial match, or no match.
+//
+// ^ALGORITHM:
+//    Trivial
+// ^^-------------------------------------------------------------------------
+static kwdmatch_t
+kwdmatch(const char * src, const char * attempt, int len =0) {
+   int  i;
+
+   if (src == attempt)  return  EXACT_MATCH ;
+   if ((src == NULL) || (attempt == NULL))  return  NO_MATCH ;
+   if ((! *src) && (! *attempt))  return  EXACT_MATCH ;
+   if ((! *src) || (! *attempt))  return  NO_MATCH ;
+
+   for (i = 0 ; ((i < len) || (len == 0)) &&
+                (attempt[i]) && (attempt[i] != ' ') ; i++) {
+      if (TOLOWER(src[i]) != TOLOWER(attempt[i]))  return  NO_MATCH ;
+   }
+
+   return  (src[i]) ? PARTIAL_MATCH : EXACT_MATCH ;
+}
+
+// **************************************************************** OptionSpec
+
+   // Class that represents an option-specification
+   //    *NOTE*:: Assumes that the char-ptr given to the constructor points
+   //             to storage that will NOT be modified and whose lifetime will
+   //             be as least as long as the OptionSpec object we construct.
+   //
+class OptionSpec {
+public:
+   OptionSpec(const char * decl =NULLSTR)
+      : hidden(0), spec(decl)
+   {
+      if (spec == NULL)  spec = NULL_spec;
+      CheckHidden();
+   }
+
+   OptionSpec(const OptionSpec & cp) : hidden(cp.hidden), spec(cp.spec) {}
+
+   // NOTE: use default destructor!
+
+      // Assign to another OptionSpec
+   OptionSpec &
+   operator=(const OptionSpec & cp) {
+      if (this != &cp) {
+         spec = cp.spec;
+         hidden = cp.hidden;
+      }
+      return *this;
+   }
+
+      // Assign to a string
+   OptionSpec &
+   operator=(const char * decl) {
+      if (spec != decl) {
+         spec = decl;
+         hidden = 0;
+         CheckHidden();
+      }
+      return *this;
+   }
+
+      // Convert to char-ptr by returning the original declaration-string
+   operator const char*() { return  isHiddenOpt() ? (spec - 1) : spec; }
+
+      // Is this option NULL?
+   int
+   isNULL(void) const { return ((spec == NULL) || (spec == NULL_spec)); }
+
+      // Is this options incorrectly specified?
+   int
+   isSyntaxError(const char * name) const;
+
+      // See if this is a Hidden option
+   int
+   isHiddenOpt(void) const { return  hidden; }
+
+      // Get the corresponding option-character
+   char
+   OptChar(void) const { return  *spec; }
+
+      // Get the corresponding long-option string
+   const char *
+   LongOpt(void) const {
+       return  (spec[1] && spec[2] && (! isspace(spec[2]))) ? (spec + 2) : NULLSTR;
+   }
+
+      // Does this option require an argument?
+   int
+   isValRequired(void) const {
+      return  ((spec[1] == ':') || (spec[1] == '+'));
+   }
+
+      // Does this option take an optional argument?
+   int
+   isValOptional(void) const {
+      return  ((spec[1] == '?') || (spec[1] == '*'));
+   }
+
+      // Does this option take no arguments?
+   int
+   isNoArg(void) const {
+      return  ((spec[1] == '|') || (! spec[1]));
+   }
+
+      // Can this option take more than one argument?
+   int
+   isList(void) const {
+      return  ((spec[1] == '+') || (spec[1] == '*'));
+   }
+
+      // Does this option take any arguments?
+   int
+   isValTaken(void) const {
+      return  (isValRequired() || isValOptional()) ;
+   }
+
+      // Format this option in the given buffer
+   unsigned
+   Format(char * buf, unsigned optctrls) const;
+
+private:
+   void
+   CheckHidden(void) {
+      if ((! hidden) && (*spec == '-')) {
+         ++hidden;
+         ++spec;
+      }
+   }
+
+   unsigned     hidden : 1;  // hidden-flag
+   const char * spec;        // string specification
+
+   static const char NULL_spec[];
+} ;
+
+const char OptionSpec::NULL_spec[] = "\0\0\0" ;
+
+int
+OptionSpec::isSyntaxError(const char * name) const {
+   int  error = 0;
+   if ((! spec) || (! *spec)) {
+      cerr << name << ": empty option specifier." << endl;
+      cerr << "\tmust be at least 1 character long." << endl;
+      ++error;
+   } else if (spec[1] && (strchr("|?:*+", spec[1]) == NULL)) {
+      cerr << name << ": bad option specifier \"" << spec << "\"." << endl;
+      cerr << "\t2nd character must be in the set \"|?:*+\"." << endl;
+      ++error;
+   }
+   return  error;
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: OptionSpec::Format - format an option-spec for a usage message
+//
+// ^SYNOPSIS:
+//    unsigned OptionSpec::Format(buf, optctrls) const
+//
+// ^PARAMETERS:
+//    char * buf -- where to print the formatted option
+//    unsigned  optctrls -- option-parsing configuration flags
+//
+// ^DESCRIPTION:
+//    Self-explanatory.
+//
+// ^REQUIREMENTS:
+//    - buf must be large enough to hold the result
+//
+// ^SIDE-EFFECTS:
+//    - writes to buf.
+//
+// ^RETURN-VALUE:
+//    Number of characters written to buf.
+//
+// ^ALGORITHM:
+//    Follow along in the source - it's not hard but it is tedious!
+// ^^-------------------------------------------------------------------------
+unsigned
+OptionSpec::Format(char * buf, unsigned optctrls) const {
+#ifdef NO_USAGE
+   return  (*buf = '\0');
+#else
+   static  char default_value[] = "<value>";
+   if (isHiddenOpt())  return (unsigned)(*buf = '\0');
+   char optchar = OptChar();
+   const char * longopt = LongOpt();
+   char * p = buf ;
+
+   const char * value = NULLSTR;
+   int    longopt_len = 0;
+   int    value_len = 0;
+
+   if (longopt) {
+      value = ::strchr(longopt, ' ');
+      longopt_len = (value) ? (value - longopt) : ::strlen(longopt);
+   } else {
+      value = ::strchr(spec + 1, ' ');
+   }
+   while (value && (*value == ' '))  ++value;
+   if (value && *value) {
+      value_len = ::strlen(value);
+   } else {
+      value = default_value;
+      value_len = sizeof(default_value) - 1;
+   }
+
+   if ((optctrls & Options::SHORT_ONLY) &&
+       ((! isNullOpt(optchar)) || (optctrls & Options::NOGUESSING))) {
+      longopt = NULLSTR;
+   }
+   if ((optctrls & Options::LONG_ONLY) &&
+       (longopt || (optctrls & Options::NOGUESSING))) {
+      optchar = '\0';
+   }
+   if (isNullOpt(optchar) && (longopt == NULL)) {
+      *buf = '\0';
+      return  0;
+   }
+
+   *(p++) = '[';
+
+   // print the single character option
+   if (! isNullOpt(optchar)) {
+      *(p++) = '-';
+      *(p++) = optchar;
+   }
+
+   if ((! isNullOpt(optchar)) && (longopt))  *(p++) = '|';
+
+   // print the long option
+   if (longopt) {
+      *(p++) = '-';
+      if (! (optctrls & (Options::LONG_ONLY | Options::SHORT_ONLY))) {
+         *(p++) = '-';
+      }
+      strncpy(p, longopt, longopt_len);
+      p += longopt_len;
+   }
+
+   // print any argument the option takes
+   if (isValTaken()) {
+      *(p++) = ' ' ;
+      if (isValOptional())  *(p++) = '[' ;
+      strcpy(p, value);
+      p += value_len;
+      if (isList()) {
+         strcpy(p, " ...");
+         p += 4;
+      }
+      if (isValOptional())  *(p++) = ']' ;
+   }
+
+   *(p++) = ']';
+   *p = '\0';
+
+   return  (unsigned) strlen(buf);
+#endif  /* USE_STDIO */
+}
+
+// ******************************************************************* Options
+
+#if (defined(MSWIN) || defined(OS2) || defined(MSDOS))
+# define DIR_SEP_CHAR '\\'
+#else
+# define DIR_SEP_CHAR '/'
+#endif
+
+Options::Options(const char * name, const char * const optv[])
+   : cmdname(name), optvec(optv), explicit_end(0), optctrls(DEFAULT),
+     nextchar(NULLSTR), listopt(NULLSTR)
+{
+   const char * basename = ::strrchr(cmdname, DIR_SEP_CHAR);
+   if (basename)  cmdname = basename + 1;
+   check_syntax();
+}
+
+Options::~Options(void) {}
+
+   // Make sure each option-specifier has correct syntax.
+   //
+   // If there is even one invalid specifier, then exit ungracefully!
+   //
+void
+Options::check_syntax(void) const {
+   int  errors = 0;
+   if ((optvec == NULL) || (! *optvec))  return;
+
+   for (const char * const * optv = optvec ; *optv ; optv++) {
+      OptionSpec  optspec = *optv;
+      errors += optspec.isSyntaxError(cmdname);
+   }
+   if (errors)  exit(127);
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::match_opt - match an option
+//
+// ^SYNOPSIS:
+//    const char * match_opt(opt, int  ignore_case) const
+//
+// ^PARAMETERS:
+//    char opt -- the option-character to match
+//    int  ignore_case -- should we ignore character-case?
+//
+// ^DESCRIPTION:
+//    See if "opt" is found in "optvec"
+//
+// ^REQUIREMENTS:
+//    - optvec should be non-NULL and terminated by a NULL pointer.
+//
+// ^SIDE-EFFECTS:
+//    None.
+//
+// ^RETURN-VALUE:
+//    NULL if no match is found,
+//    otherwise a pointer to the matching option-spec.
+//
+// ^ALGORITHM:
+//    foreach option-spec
+//       - see if "opt" is a match, if so return option-spec
+//    end-for
+// ^^-------------------------------------------------------------------------
+const char *
+Options::match_opt(char opt, int ignore_case) const {
+   if ((optvec == NULL) || (! *optvec))  return  NULLSTR;
+
+   for (const char * const * optv = optvec ; *optv ; optv++) {
+      OptionSpec  optspec = *optv;
+      char optchar = optspec.OptChar();
+      if (isNullOpt(optchar))  continue;
+      if (opt == optchar) {
+         return  optspec;
+      } else if (ignore_case && (TOLOWER(opt) == TOLOWER(optchar))) {
+         return  optspec;
+      }
+   }
+
+   return  NULLSTR;  // not found
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::match_longopt - match a long-option
+//
+// ^SYNOPSIS:
+//   const char * Options::match_longopt(opt, len, ambiguous)
+//
+// ^PARAMETERS:
+//    char * opt -- the long-option to match
+//    int len -- the number of character of "opt" to match
+//    int & ambiguous -- set by this routine before returning.
+//
+// ^DESCRIPTION:
+//    Try to match "opt" against some unique prefix of a long-option
+//    (case insensitive).
+//
+// ^REQUIREMENTS:
+//    - optvec should be non-NULL and terminated by a NULL pointer.
+//
+// ^SIDE-EFFECTS:
+//    - *ambiguous is set to '1' if "opt" matches >1 long-option
+//      (otherwise it is set to 0).
+//
+// ^RETURN-VALUE:
+//    NULL if no match is found,
+//    otherwise a pointer to the matching option-spec.
+//
+// ^ALGORITHM:
+//    ambiguous is FALSE
+//    foreach option-spec
+//       if we have an EXACT-MATCH, return the option-spec
+//       if we have a partial-match then
+//          if we already had a previous partial match then
+//             set ambiguous = TRUE and return NULL
+//          else
+//             remember this options spec and continue matching
+//          end-if
+//       end-if
+//    end-for
+//    if we had exactly 1 partial match return it, else return NULL
+// ^^-------------------------------------------------------------------------
+const char *
+Options::match_longopt(const char * opt, int  len, int & ambiguous) const {
+   kwdmatch_t  result;
+   const char * matched = NULLSTR ;
+
+   ambiguous = 0;
+   if ((optvec == NULL) || (! *optvec))  return  NULLSTR;
+
+   for (const char * const * optv = optvec ; *optv ; optv++) {
+      OptionSpec  optspec = *optv;
+      const char * longopt = optspec.LongOpt();
+      if (longopt == NULL)  continue;
+      result = kwdmatch(longopt, opt, len);
+      if (result == EXACT_MATCH) {
+         return  optspec;
+      } else if (result == PARTIAL_MATCH) {
+         if (matched) {
+            ++ambiguous;
+            return  NULLSTR;
+         } else {
+            matched = optspec;
+         }
+      }
+   }//for
+
+   return  matched;
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::parse_opt - parse an option
+//
+// ^SYNOPSIS:
+//    int Options::parse_opt(iter, optarg)
+//
+// ^PARAMETERS:
+//    OptIter & iter -- option iterator
+//    const char * & optarg -- where to store any option-argument
+//
+// ^DESCRIPTION:
+//    Parse the next option in iter (advancing as necessary).
+//    Make sure we update the nextchar pointer along the way. Any option
+//    we find should be returned and optarg should point to its argument.
+//
+// ^REQUIREMENTS:
+//    - nextchar must point to the prospective option character
+//
+// ^SIDE-EFFECTS:
+//    - iter is advanced when an argument completely parsed
+//    - optarg is modified to point to any option argument
+//    - if Options::QUIET is not set, error messages are printed on cerr
+//
+// ^RETURN-VALUE:
+//    'c' if the -c option was matched (optarg points to its argument)
+//    BADCHAR if the option is invalid (optarg points to the bad
+//                                                   option-character).
+//
+// ^ALGORITHM:
+//    It gets complicated -- follow the comments in the source.
+// ^^-------------------------------------------------------------------------
+int
+Options::parse_opt(OptIter & iter, const char * & optarg) {
+   listopt = NULLSTR;  // reset the list pointer
+
+   if ((optvec == NULL) || (! *optvec))  return  Options::ENDOPTS;
+
+      // Try to match a known option
+   OptionSpec optspec = match_opt(*(nextchar++), (optctrls & Options::ANYCASE));
+
+      // Check for an unknown option
+   if (optspec.isNULL()) {
+      // See if this was a long-option in disguise
+      if (! (optctrls & Options::NOGUESSING)) {
+         unsigned  save_ctrls = optctrls;
+         const char * save_nextchar = nextchar;
+         nextchar -= 1;
+         optctrls |= (Options::QUIET | Options::NOGUESSING);
+         int  optchar = parse_longopt(iter, optarg);
+         optctrls = save_ctrls;
+         if (optchar > 0) {
+            return  optchar;
+         } else {
+            nextchar = save_nextchar;
+         }
+      }
+      if (! (optctrls & Options::QUIET)) {
+         cerr << cmdname << ": unknown option -"
+              << *(nextchar - 1) << "." << endl ;
+      }
+      optarg = (nextchar - 1);  // record the bad option in optarg
+      return  Options::BADCHAR;
+   }
+
+      // If no argument is taken, then leave now
+   if (optspec.isNoArg()) {
+      optarg = NULLSTR;
+      return  optspec.OptChar();
+   }
+
+      // Check for argument in this arg
+   if (*nextchar) {
+      optarg = nextchar; // the argument is right here
+      nextchar = NULLSTR;   // we've exhausted this arg
+      if (optspec.isList())  listopt = optspec ;  // save the list-spec
+      return  optspec.OptChar();
+   }
+
+      // Check for argument in next arg
+   const char * nextarg = iter.curr();
+   if ((nextarg != NULL)  &&
+       (optspec.isValRequired() || (! isOption(optctrls, nextarg)))) {
+      optarg = nextarg;    // the argument is here
+      iter.next();         // end of arg - advance
+      if (optspec.isList())  listopt = optspec ;  // save the list-spec
+      return  optspec.OptChar();
+   }
+
+     // No argument given - if its required, thats an error
+   optarg = NULLSTR;
+   if (optspec.isValRequired() &&  !(optctrls & Options::QUIET)) {
+      cerr << cmdname << ": argument required for -" << optspec.OptChar()
+           << " option." << endl ;
+   }
+   return  optspec.OptChar();
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::parse_longopt - parse a long-option
+//
+// ^SYNOPSIS:
+//    int Options::parse_longopt(iter, optarg)
+//
+// ^PARAMETERS:
+//    OptIter & iter -- option iterator
+//    const char * & optarg -- where to store any option-argument
+//
+// ^DESCRIPTION:
+//    Parse the next long-option in iter (advancing as necessary).
+//    Make sure we update the nextchar pointer along the way. Any option
+//    we find should be returned and optarg should point to its argument.
+//
+// ^REQUIREMENTS:
+//    - nextchar must point to the prospective option character
+//
+// ^SIDE-EFFECTS:
+//    - iter is advanced when an argument completely parsed
+//    - optarg is modified to point to any option argument
+//    - if Options::QUIET is not set, error messages are printed on cerr
+//
+// ^RETURN-VALUE:
+//    'c' if the the long-option corresponding to the -c option was matched
+//         (optarg points to its argument)
+//    BADKWD if the option is invalid (optarg points to the bad long-option
+//                                                                     name).
+//
+// ^ALGORITHM:
+//    It gets complicated -- follow the comments in the source.
+// ^^-------------------------------------------------------------------------
+int
+Options::parse_longopt(OptIter & iter, const char * & optarg) {
+   int  len = 0, ambiguous = 0;
+
+   listopt = NULLSTR ;  // reset the list-spec
+
+   if ((optvec == NULL) || (! *optvec))  return  Options::ENDOPTS;
+
+      // if a value is supplied in this argv element, get it now
+   const char * val = strpbrk(nextchar, ":=") ;
+   if (val) {
+      len = val - nextchar ;
+      ++val ;
+   }
+
+      // Try to match a known long-option
+   OptionSpec  optspec = match_longopt(nextchar, len, ambiguous);
+
+      // Check for an unknown long-option
+   if (optspec.isNULL()) {
+      // See if this was a short-option in disguise
+      if ((! ambiguous) && (! (optctrls & Options::NOGUESSING))) {
+         unsigned  save_ctrls = optctrls;
+         const char * save_nextchar = nextchar;
+         optctrls |= (Options::QUIET | Options::NOGUESSING);
+         int  optchar = parse_opt(iter, optarg);
+         optctrls = save_ctrls;
+         if (optchar > 0) {
+            return  optchar;
+         } else {
+            nextchar = save_nextchar;
+         }
+      }
+      if (! (optctrls & Options::QUIET)) {
+         cerr << cmdname << ": " << ((ambiguous) ? "ambiguous" : "unknown")
+              << " option "
+              << ((optctrls & Options::LONG_ONLY) ? "-" : "--")
+              << nextchar << "." << endl ;
+      }
+      optarg = nextchar;  // record the bad option in optarg
+      nextchar = NULLSTR;    // we've exhausted this argument
+      return  (ambiguous) ? Options::AMBIGUOUS : Options::BADKWD;
+   }
+
+      // If no argument is taken, then leave now
+   if (optspec.isNoArg()) {
+      if ((val) && ! (optctrls & Options::QUIET)) {
+         cerr << cmdname << ": option "
+              << ((optctrls & Options::LONG_ONLY) ? "-" : "--")
+              << optspec.LongOpt() << " does NOT take an argument." << endl ;
+      }
+      optarg = val;     // record the unexpected argument
+      nextchar = NULLSTR;  // we've exhausted this argument
+      return  optspec.OptChar();
+   }
+
+      // Check for argument in this arg
+   if (val) {
+      optarg = val;      // the argument is right here
+      nextchar = NULLSTR;   // we exhausted the rest of this arg
+      if (optspec.isList())  listopt = optspec ;  // save the list-spec
+      return  optspec.OptChar();
+   }
+
+      // Check for argument in next arg
+   const char * nextarg = iter.curr();  // find the next argument to parse
+   if ((nextarg != NULL)  &&
+       (optspec.isValRequired() || (! isOption(optctrls, nextarg)))) {
+      optarg = nextarg;        // the argument is right here
+      iter.next();             // end of arg - advance
+      nextchar = NULLSTR;         // we exhausted the rest of this arg
+      if (optspec.isList())  listopt = optspec ;  // save the list-spec
+      return  optspec.OptChar();
+   }
+
+     // No argument given - if its required, thats an error
+   optarg = NULLSTR;
+   if (optspec.isValRequired() &&  !(optctrls & Options::QUIET)) {
+      const char * longopt = optspec.LongOpt();
+      const char * spc = ::strchr(longopt, ' ');
+      int  longopt_len;
+      if (spc) {
+         longopt_len = spc - longopt;
+      } else {
+         longopt_len = ::strlen(longopt);
+      }
+      cerr << cmdname << ": argument required for "
+           << ((optctrls & Options::LONG_ONLY) ? "-" : "--");
+      cerr.write(longopt, longopt_len) << " option." << endl ;
+   }
+   nextchar = NULLSTR;           // we exhausted the rest of this arg
+   return  optspec.OptChar();
+}
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::usage - print usage
+//
+// ^SYNOPSIS:
+//    void Options::usage(os, positionals)
+//
+// ^PARAMETERS:
+//    ostream & os -- where to print the usage
+//    char * positionals -- command-line syntax for any positional args
+//
+// ^DESCRIPTION:
+//    Print command-usage (using either option or long-option syntax) on os.
+//
+// ^REQUIREMENTS:
+//    os should correspond to an open output file.
+//
+// ^SIDE-EFFECTS:
+//    Prints on os
+//
+// ^RETURN-VALUE:
+//    None.
+//
+// ^ALGORITHM:
+//    Print usage on os, wrapping long lines where necessary.
+// ^^-------------------------------------------------------------------------
+void
+Options::usage(ostream & os, const char * positionals) const {
+#ifdef NO_USAGE
+   return;
+#else
+   const char * const * optv = optvec;
+   unsigned  cols = 79;
+   int  first, nloop;
+   char  buf[256] ;
+
+   if ((optv == NULL) || (! *optv))  return;
+
+      // print first portion "usage: progname"
+   os << "usage: " << cmdname ;
+   unsigned  ll = strlen(cmdname) + 7;
+
+      // save the current length so we know how much space to skip for
+      // subsequent lines.
+      //
+   unsigned  margin = ll + 1;
+
+      // print the options and the positional arguments
+   for (nloop = 0, first = 1 ; !nloop ; optv++, first = 0) {
+      unsigned  len;
+      OptionSpec   optspec = *optv;
+
+         // figure out how wide this parameter is (for printing)
+      if (! *optv) {
+         len = strlen(positionals);
+         ++nloop;  // terminate this loop
+      } else {
+         if (optspec.isHiddenOpt())  continue;
+         len = optspec.Format(buf, optctrls);
+      }
+
+      //  Will this fit?
+      if ((ll + len + 1) > (cols - first)) {
+         os << '\n' ;  // No - start a new line;
+#ifdef USE_STDIO
+         for (int _i_ = 0; _i_ < margin; ++_i_)  os << " ";
+#else
+         os.width(margin); os << "" ;
+#endif
+         ll = margin;
+      } else {
+         os << ' ' ;  // Yes - just throw in a space
+         ++ll;
+      }
+      ll += len;
+      os << ((nloop) ? positionals : buf) ;
+   }// for each ad
+
+   os << endl ;
+#endif  /* NO_USAGE */
+}
+
+
+// ---------------------------------------------------------------------------
+// ^FUNCTION: Options::operator() - get options from the command-line
+//
+// ^SYNOPSIS:
+//   int Options::operator()(iter, optarg)
+//
+// ^PARAMETERS:
+//    OptIter & iter -- option iterator
+//    const char * & optarg -- where to store any option-argument
+//
+// ^DESCRIPTION:
+//    Parse the next option in iter (advancing as necessary).
+//    Make sure we update the nextchar pointer along the way. Any option
+//    we find should be returned and optarg should point to its argument.
+//
+// ^REQUIREMENTS:
+//    None.
+//
+// ^SIDE-EFFECTS:
+//    - iter is advanced when an argument is completely parsed
+//    - optarg is modified to point to any option argument
+//    - if Options::QUIET is not set, error messages are printed on cerr
+//
+// ^RETURN-VALUE:
+//     0 if all options have been parsed.
+//    'c' if the the option or long-option corresponding to the -c option was
+//         matched (optarg points to its argument).
+//    BADCHAR if the option is invalid (optarg points to the bad option char).
+//    BADKWD if the option is invalid (optarg points to the bad long-opt name).
+//    AMBIGUOUS if an ambiguous keyword name was given (optarg points to the
+//         ambiguous keyword name).
+//    POSITIONAL if PARSE_POS was set and the current argument is a positional
+//         parameter (in which case optarg points to the positional argument).
+//
+// ^ALGORITHM:
+//    It gets complicated -- follow the comments in the source.
+// ^^-------------------------------------------------------------------------
+int
+Options::operator()(OptIter & iter, const char * & optarg) {
+   int parse_opts_only = isOptsOnly(optctrls);
+   if (parse_opts_only)  explicit_end = 0;
+
+      // See if we have an option left over from before ...
+   if ((nextchar) && *nextchar) {
+      return  parse_opt(iter, optarg);
+   }
+
+      // Check for end-of-options ...
+   const char * arg = NULLSTR;
+   int get_next_arg = 0;
+   do {
+      arg = iter.curr();
+      get_next_arg = 0;
+      if (arg == NULL) {
+         listopt = NULLSTR;
+         return  Options::ENDOPTS;
+      } else if ((! explicit_end) && isEndOpts(arg)) {
+         iter.next();   // advance past end-of-options arg
+         listopt = NULLSTR;
+         explicit_end = 1;
+         if (parse_opts_only)  return  Options::ENDOPTS;
+         get_next_arg = 1;  // make sure we look at the next argument.
+      }
+   } while (get_next_arg);
+
+      // Do we have a positional arg?
+   if ( explicit_end || (! isOption(optctrls, arg)) ) {
+      if (parse_opts_only) {
+         return  Options::ENDOPTS;
+      } else {
+         optarg = arg;  // set optarg to the positional argument
+         iter.next();   // advance iterator to the next argument
+         return  Options::POSITIONAL;
+      }
+   }
+
+   iter.next();  // pass the argument that arg already points to
+
+      // See if we have a long option ...
+   if (! (optctrls & Options::SHORT_ONLY)) {
+      if ((*arg == '-') && (arg[1] == '-')) {
+         nextchar = arg + 2;
+         return  parse_longopt(iter, optarg);
+      } else if ((optctrls & Options::PLUS) && (*arg == '+')) {
+         nextchar = arg + 1;
+         return  parse_longopt(iter, optarg);
+      }
+   }
+   if (*arg == '-') {
+      nextchar = arg + 1;
+      if (optctrls & Options::LONG_ONLY) {
+         return  parse_longopt(iter, optarg);
+      } else {
+         return  parse_opt(iter, optarg);
+      }
+   }
+
+      // If we get here - it is because we have a list value
+   OptionSpec  optspec = listopt;
+   optarg = arg ;        // record the list value
+   return  optspec.OptChar() ;
+}
+
diff --git a/tools/elftosb/common/options.h b/tools/elftosb/common/options.h
new file mode 100644 (file)
index 0000000..0c4e49c
--- /dev/null
@@ -0,0 +1,488 @@
+// ****************************************************************************
+// ^FILE: options.h - option parsing classes
+//
+// ^DESCRIPTION:
+//    This file defines classes used to parse command-line options.
+//    Options may be parsed from an array of strings, or from any structure
+//    for which a corresponding option-iterator exists.
+//
+// ^HISTORY:
+//    03/06/92  Brad Appleton   <bradapp@enteract.com>   Created
+//
+//    03/23/93 Brad Appleton   <bradapp@enteract.com>
+//    - Added OptIstreamIter class
+//
+//    03/08/94 Brad Appleton   <bradapp@enteract.com>
+//    - Added Options::reset() member function
+//
+//    07/31/97 Brad Appleton   <bradapp@enteract.com>
+//    - Added PARSE_POS control flag and POSITIONAL return value
+//
+//       04/30/06  Chris Reed
+//    - Updated to modern C++ and STL
+//    - Converted comments to doxygen style
+// ^^**************************************************************************
+
+#ifndef _options_h
+#define _options_h
+
+#ifdef USE_STDIO
+       #include <stdio.h>
+#else
+       #include <iostream>
+#endif
+
+
+//! Abstract class to iterate through options/arguments
+//!
+class OptIter {
+public:
+   OptIter(void) {}
+   virtual ~OptIter(void);
+
+      //! curr() returns the current item in the iterator without
+      //! advancing on to the next item. If we are at the end of items
+      //! then NULL is returned.
+   virtual const char *
+   curr(void) = 0;
+
+      //! next() advances to the next item.
+   virtual void
+   next(void) = 0;
+
+      //! operator() returns the current item in the iterator and then
+      //! advances on to the next item. If we are at the end of items
+      //! then NULL is returned.
+   virtual const char *
+   operator()(void);
+} ;
+
+//! Abstract class for a rewindable OptIter
+//!
+class OptIterRwd : public OptIter {
+public:
+   OptIterRwd(void);
+
+   virtual ~OptIterRwd(void);
+
+   virtual const char *
+   curr(void) = 0;
+
+   virtual void
+   next(void) = 0;
+
+   virtual const char *
+   operator()(void) = 0;
+
+      //! rewind() resets the "current-element" to the first one in the "list"
+   virtual void
+   rewind(void) = 0;
+} ;
+
+//! Class to iterate through an array of tokens. The array may be terminated
+//! by NULL or a count containing the number of tokens may be given.
+//!
+class OptArgvIter : public OptIterRwd {
+private:
+   int            ndx;   // index of current arg
+   int            ac;    // arg count
+   const char * const * av;  // arg vector
+
+public:
+   OptArgvIter(const char * const argv[])
+      : av(argv), ac(-1), ndx(0) {}
+
+   OptArgvIter(int argc, const char * const argv[])
+      : av(argv), ac(argc), ndx(0) {}
+
+   virtual
+   ~OptArgvIter(void);
+
+   virtual const char *
+   curr(void);
+
+   virtual void
+   next(void);
+
+   virtual const char *
+   operator()(void);
+
+   virtual void
+   rewind(void);
+
+      //! index returns the current index to use for argv[]
+   int index(void)  { return  ndx; }
+} ;
+
+
+//! Class to iterate through a string containing delimiter-separated tokens
+//!
+class OptStrTokIter : public OptIterRwd {
+private:
+   unsigned     len;        // length of token-string
+   const char * str;        // the token-string
+   const char * seps;       // delimiter-set (separator-characters)
+   const char * cur;        // current token
+   char       * tokstr;     // our copy of the token-string
+
+   static const char * default_delims;  // default delimiters = whitespace
+
+public:
+   OptStrTokIter(const char * tokens, const char * delimiters =0);
+
+   virtual
+   ~OptStrTokIter(void);
+
+   virtual const char *
+   curr(void);
+
+   virtual void
+   next(void);
+
+   virtual const char *
+   operator()(void);
+
+   virtual void
+   rewind(void);
+
+      //! delimiters() with NO arguments returns the current set of delimiters,
+      //! If an argument is given then it is used as the new set of delimiters.
+   const char *
+   delimiters(void)  { return  seps; }
+
+   void
+   delimiters(const char * delims) {
+      seps = (delims) ? delims : default_delims ;
+   }
+} ;
+
+
+//! OptIstreamIter is a class for iterating over arguments that come
+//! from an input stream. Each line of the input stream is considered
+//! to be a set of white-space separated tokens. If the the first
+//! non-white character on a line is '#' ('!' for VMS systems) then
+//! the line is considered a comment and is ignored.
+//!
+//! \note If a line is more than 1022 characters in length then we
+//! treat it as if it were several lines of length 1022 or less.
+//!
+//! \note The string tokens returned by this iterator are pointers
+//!         to temporary buffers which may not necessarily stick around
+//!         for too long after the call to curr() or operator(), hence
+//!         if you need the string value to persist - you will need to
+//!         make a copy.
+//!
+class OptIstreamIter : public OptIter {
+private:
+   std::istream & is ;
+   OptStrTokIter * tok_iter ;
+
+   void
+   fill(void);
+
+public:
+   static const unsigned  MAX_LINE_LEN ;
+
+   OptIstreamIter(std::istream & input);
+
+   virtual
+   ~OptIstreamIter(void);
+
+   virtual const char *
+   curr(void);
+
+   virtual void
+   next(void);
+
+   virtual const char *
+   operator()(void);
+} ;
+
+
+//! \brief parse command-line options
+//!
+//! \section Synopsis
+//! \code
+//!   #include <options.h>
+//!
+//!   Options opts(cmdname, optv);
+//!   char cmdname[], *optv[];
+//! \endcode
+//! \section Description
+//! The Options constructor expects a command-name (usually argv[0]) and
+//! a pointer to an array of strings.  The last element in this array MUST
+//! be NULL. Each non-NULL string in the array must have the following format:
+//!
+//!   The 1st character must be the option-name ('c' for a -c option).
+//!
+//!   The 2nd character must be one of '|', '?', ':', '*', or '+'.
+//!      '|' -- indicates that the option takes NO argument;
+//!      '?' -- indicates that the option takes an OPTIONAL argument;
+//!      ':' -- indicates that the option takes a REQUIRED argument;
+//!      '*' -- indicates that the option takes 0 or more arguments;
+//!      '+' -- indicates that the option takes 1 or more arguments;
+//!
+//!   The remainder of the string must be the long-option name.
+//!
+//!   If desired, the long-option name may be followed by one or more
+//!   spaces and then by the name of the option value. This name will
+//!   be used when printing usage messages. If the option-value-name
+//!   is not given then the string "<value>" will be used in usage
+//!   messages.
+//!
+//!   One may use a space to indicate that a particular option does not
+//!   have a corresponding long-option.  For example, "c: " (or "c:")
+//!   means the -c option takes a value & has NO corresponding long-option.
+//!
+//!   To specify a long-option that has no corresponding single-character
+//!   option is a bit trickier: Options::operator() still needs an "option-
+//!   character" to return when that option is matched. One may use a whitespace
+//!   character or a non-printable character as the single-character option
+//!   in such a case. (hence " |hello" would only match "--hello").
+//!
+//!   \section Exceptions Exceptions to the above
+//!   If the 1st character of the string is '-', then the rest of the
+//!   string must correspond to the above format, and the option is
+//!   considered to be a hidden-option. This means it will be parsed
+//!   when actually matching options from the command-line, but will
+//!   NOT show-up if a usage message is printed using the usage() member
+//!   function. Such an example might be "-h|hidden". If you want to
+//!   use any "dummy" options (options that are not parsed, but that
+//!   to show up in the usage message), you can specify them along with
+//!   any positional parameters to the usage() member function.
+//!
+//!   If the 2nd character of the string is '\0' then it is assumed
+//!   that there is no corresponding long-option and that the option
+//!   takes no argument (hence "f", and "f| " are equivalent).
+//!
+//!   \code
+//!      const char * optv[] = {
+//!          "c:count   <number>",
+//!          "s?str     <string>",
+//!          "x",
+//!          " |hello",
+//!          "g+groups  <newsgroup>",
+//!          NULL
+//!      } ;
+//!    \endcode
+//!      optv[] now corresponds to the following:
+//!
+//!            usage: cmdname [-c|--count <number>] [-s|--str [<string>]]
+//!                           [-x] [--hello] [-g|--groups <newsgroup> ...]
+//!
+//! Long-option names are matched case-insensitive and only a unique prefix
+//! of the name needs to be specified.
+//!
+//! Option-name characters are case-sensitive!
+//!
+//! \section Caveat
+//! Because of the way in which multi-valued options and options with optional
+//! values are handled, it is NOT possible to supply a value to an option in
+//! a separate argument (different argv[] element) if the value is OPTIONAL
+//! and begins with a '-'. What this means is that if an option "-s" takes an
+//! optional value value and you wish to supply a value of "-foo" then you must
+//! specify this on the command-line as "-s-foo" instead of "-s -foo" because
+//! "-s -foo" will be considered to be two separate sets of options.
+//!
+//! A multi-valued option is terminated by another option or by the end-of
+//! options. The following are all equivalent (if "-l" is a multi-valued
+//! option and "-x" is an option that takes no value):
+//!
+//!    cmdname -x -l item1 item2 item3 -- arg1 arg2 arg3
+//!    cmdname -x -litem1 -litem2 -litem3 -- arg1 arg2 arg3
+//!    cmdname -l item1 item2 item3 -x arg1 arg2 arg3
+//!
+//!
+//! \code
+//!    #include <options.h>
+//!
+//!    static const char * optv[] = {
+//!       "H|help",
+//!       "c:count   <number>",
+//!       "s?str     <string>",
+//!       "x",
+//!       " |hello",
+//!       "g+groups  <newsgroup>",
+//!       NULL
+//!    } ;
+//!
+//!    main(int argc, char * argv[]) {
+//!       int  optchar;
+//!       const char * optarg;
+//!       const char * str = "default_string";
+//!       int  count = 0, xflag = 0, hello = 0;
+//!       int  errors = 0, ngroups = 0;
+//!    
+//!       Options  opts(*argv, optv);
+//!       OptArgvIter  iter(--argc, ++argv);
+//!    
+//!       while( optchar = opts(iter, optarg) ) {
+//!          switch (optchar) {
+//!          case 'H' :
+//!             opts.usage(cout, "files ...");
+//!             exit(0);
+//!             break;
+//!          case 'g' :
+//!             ++ngroups; break;  //! the groupname is in "optarg"
+//!          case 's' :
+//!             str = optarg; break;
+//!          case 'x' :
+//!             ++xflag; break;
+//!          case ' ' :
+//!             ++hello; break;
+//!          case 'c' :
+//!             if (optarg == NULL)  ++errors;
+//!             else  count = (int) atol(optarg);
+//!             break;
+//!          default :  ++errors; break;
+//!          } //!switch
+//!       }
+//!    
+//!       if (errors || (iter.index() == argc)) {
+//!          if (! errors) {
+//!             cerr << opts.name() << ": no filenames given." << endl ;
+//!          }
+//!          opts.usage(cerr, "files ...");
+//!          exit(1);
+//!       }
+//!    
+//!       cout << "xflag=" << ((xflag) ? "ON"  : "OFF") << endl
+//!            << "hello=" << ((hello) ? "YES" : "NO") << endl
+//!            << "count=" << count << endl
+//!            << "str=\"" << ((str) ? str : "No value given!") << "\"" << endl
+//!            << "ngroups=" << ngroups << endl ;
+//!    
+//!       if (iter.index() < argc) {
+//!          cout << "files=" ;
+//!          for (int i = iter.index() ; i < argc ; i++) {
+//!             cout << "\"" << argv[i] << "\" " ;
+//!          }
+//!          cout << endl ;
+//!       }
+//!    }
+//! \endcode
+class Options {
+private:
+   unsigned       explicit_end : 1;  //!< were we terminated because of "--"?
+   unsigned       optctrls : 7;  //!< control settings (a set of OptCtrl masks)
+   const char  * const * optvec; //!< vector of option-specifications (last=NULL)
+   const char   * nextchar;      //!< next option-character to process
+   const char   * listopt;       //!< last list-option we matched
+   const char   * cmdname;       //!< name of the command
+
+   void
+   check_syntax(void) const;
+
+   const char *
+   match_opt(char opt, int ignore_case =0) const;
+
+   const char *
+   match_longopt(const char * opt, int  len, int & ambiguous) const;
+
+   int
+   parse_opt(OptIter & iter, const char * & optarg);
+
+   int
+   parse_longopt(OptIter & iter, const char * & optarg);
+
+public:
+   enum OptCtrl {
+      DEFAULT    = 0x00,  //!< Default setting
+      ANYCASE    = 0x01,  //!< Ignore case when matching short-options
+      QUIET      = 0x02,  //!< Dont print error messages
+      PLUS       = 0x04,  //!< Allow "+" as a long-option prefix
+      SHORT_ONLY = 0x08,  //!< Dont accept long-options
+      LONG_ONLY  = 0x10,  //!< Dont accept short-options
+                            //!< (also allows "-" as a long-option prefix).
+      NOGUESSING = 0x20,  //!< Normally, when we see a short (long) option
+                            //!< on the command line that doesnt match any
+                            //!< known short (long) options, then we try to
+                            //!< "guess" by seeing if it will match any known
+                            //!< long (short) option. Setting this mask prevents
+                            //!< this "guessing" from occurring.
+      PARSE_POS = 0x40    //!< By default, Options will not present positional
+                            //!< command-line arguments to the user and will
+                            //!< instead stop parsing when the first positonal
+                            //!< argument has been encountered. If this flag
+                            //!< is given, Options will present positional
+                            //!< arguments to the user with a return code of
+                            //!< POSITIONAL; ENDOPTS will be returned only
+                            //!< when the end of the argument list is reached.
+   } ;
+
+      //! Error return values for operator()
+      //!
+   enum OptRC {
+      ENDOPTS    =  0,
+      BADCHAR    = -1,
+      BADKWD     = -2,
+      AMBIGUOUS  = -3,
+      POSITIONAL = -4
+   } ;
+
+   Options(const char * name, const char * const optv[]);
+
+   virtual
+   ~Options(void);
+
+      //! name() returns the command name
+   const char *
+   name(void) const { return  cmdname; }
+
+      //! ctrls() (with no arguments) returns the existing control settings
+   unsigned
+   ctrls(void) const { return  optctrls; }
+
+      //! ctrls() (with 1 argument) sets new control settings
+   void
+   ctrls(unsigned newctrls) { optctrls = newctrls; }
+
+      //! reset for another pass to parse for options
+   void
+   reset(void) { nextchar = listopt = NULL; }
+  
+      //! usage() prints options usage (followed by any positional arguments
+      //! listed in the parameter "positionals") on the given outstream
+   void
+   usage(std::ostream & os, const char * positionals) const ;
+
+      //! operator() iterates through the arguments as necessary (using the
+      //! given iterator) and returns the character value of the option
+      //! (or long-option) that it matched. If the option has a value
+      //! then the value given may be found in optarg (otherwise optarg
+      //! will be NULL).
+      //!
+      //! 0 is returned upon end-of-options. At this point, "iter" may
+      //! be used to process any remaining positional parameters. If the
+      //! PARSE_POS control-flag is set then 0 is returned only when all
+      //! arguments in "iter" have been exhausted.
+      //!
+      //! If an invalid option is found then BADCHAR is returned and *optarg
+      //! is the unrecognized option character.
+      //!
+      //! If an invalid long-option is found then BADKWD is returned and optarg
+      //! points to the bad long-option.
+      //!
+      //! If an ambiguous long-option is found then AMBIGUOUS is returned and
+      //! optarg points to the ambiguous long-option.
+      //!
+      //! If the PARSE_POS control-flag is set then POSITIONAL is returned
+      //! when a positional argument is encountered and optarg points to
+      //! the positonal argument (and "iter" is advanced to the next argument
+      //! in the iterator).
+      //!
+      //! Unless Options::QUIET is used, missing option-arguments and
+      //! invalid options (and the like) will automatically cause error
+      //! messages to be issued to cerr.
+   int
+   operator()(OptIter & iter, const char * & optarg) ;
+
+      //! Call this member function after operator() has returned 0
+      //! if you want to know whether or not options were explicitly
+      //! terminated because "--" appeared on the command-line.
+      //!
+   int
+   explicit_endopts() const { return  explicit_end; }
+} ;
+
+#endif /* _options_h */
diff --git a/tools/elftosb/common/rijndael.cpp b/tools/elftosb/common/rijndael.cpp
new file mode 100644 (file)
index 0000000..5708711
--- /dev/null
@@ -0,0 +1,1604 @@
+//
+// File : rijndael.cpp
+// Creation date : Sun Nov 5 2000 03:22:10 CEST
+// Author : Szymon Stefanek (stefanek@tin.it)
+//
+// Another implementation of the Rijndael cipher.
+// This is intended to be an easily usable library file.
+// This code is public domain.
+// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
+//
+
+//
+// Original Copyright notice:
+//
+//    rijndael-alg-fst.c   v2.4   April '2000
+//    rijndael-alg-fst.h
+//    rijndael-api-fst.c
+//    rijndael-api-fst.h
+//
+//    Optimised ANSI C code
+//
+//    authors: v1.0: Antoon Bosselaers
+//             v2.0: Vincent Rijmen, K.U.Leuven
+//             v2.3: Paulo Barreto
+//             v2.4: Vincent Rijmen, K.U.Leuven
+//
+//    This code is placed in the public domain.
+//
+
+//
+// This implementation works on 128 , 192 , 256 bit keys
+// and on 128 bit blocks
+//
+
+#define _RIJNDAEL_CPP_
+
+#include "rijndael.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static uint8_t S[256]=
+{
+        99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254, 215, 171, 118, 
+       202, 130, 201, 125, 250,  89,  71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 
+       183, 253, 147,  38,  54,  63, 247, 204,  52, 165, 229, 241, 113, 216,  49,  21, 
+         4, 199,  35, 195,  24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117, 
+         9, 131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,  47, 132, 
+        83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,  57,  74,  76,  88, 207, 
+       208, 239, 170, 251,  67,  77,  51, 133,  69, 249,   2, 127,  80,  60, 159, 168, 
+        81, 163,  64, 143, 146, 157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 
+       205,  12,  19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25, 115, 
+        96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20, 222,  94,  11, 219, 
+       224,  50,  58,  10,  73,   6,  36,  92, 194, 211, 172,  98, 145, 149, 228, 121, 
+       231, 200,  55, 109, 141, 213,  78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 
+       186, 120,  37,  46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138, 
+       112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134, 193,  29, 158, 
+       225, 248, 152,  17, 105, 217, 142, 148, 155,  30, 135, 233, 206,  85,  40, 223, 
+       140, 161, 137,  13, 191, 230,  66, 104,  65, 153,  45,  15, 176,  84, 187,  22
+};
+
+
+static uint8_t T1[256][4]=
+{
+       0xc6,0x63,0x63,0xa5, 0xf8,0x7c,0x7c,0x84, 0xee,0x77,0x77,0x99, 0xf6,0x7b,0x7b,0x8d, 
+       0xff,0xf2,0xf2,0x0d, 0xd6,0x6b,0x6b,0xbd, 0xde,0x6f,0x6f,0xb1, 0x91,0xc5,0xc5,0x54, 
+       0x60,0x30,0x30,0x50, 0x02,0x01,0x01,0x03, 0xce,0x67,0x67,0xa9, 0x56,0x2b,0x2b,0x7d, 
+       0xe7,0xfe,0xfe,0x19, 0xb5,0xd7,0xd7,0x62, 0x4d,0xab,0xab,0xe6, 0xec,0x76,0x76,0x9a, 
+       0x8f,0xca,0xca,0x45, 0x1f,0x82,0x82,0x9d, 0x89,0xc9,0xc9,0x40, 0xfa,0x7d,0x7d,0x87, 
+       0xef,0xfa,0xfa,0x15, 0xb2,0x59,0x59,0xeb, 0x8e,0x47,0x47,0xc9, 0xfb,0xf0,0xf0,0x0b, 
+       0x41,0xad,0xad,0xec, 0xb3,0xd4,0xd4,0x67, 0x5f,0xa2,0xa2,0xfd, 0x45,0xaf,0xaf,0xea, 
+       0x23,0x9c,0x9c,0xbf, 0x53,0xa4,0xa4,0xf7, 0xe4,0x72,0x72,0x96, 0x9b,0xc0,0xc0,0x5b, 
+       0x75,0xb7,0xb7,0xc2, 0xe1,0xfd,0xfd,0x1c, 0x3d,0x93,0x93,0xae, 0x4c,0x26,0x26,0x6a, 
+       0x6c,0x36,0x36,0x5a, 0x7e,0x3f,0x3f,0x41, 0xf5,0xf7,0xf7,0x02, 0x83,0xcc,0xcc,0x4f, 
+       0x68,0x34,0x34,0x5c, 0x51,0xa5,0xa5,0xf4, 0xd1,0xe5,0xe5,0x34, 0xf9,0xf1,0xf1,0x08, 
+       0xe2,0x71,0x71,0x93, 0xab,0xd8,0xd8,0x73, 0x62,0x31,0x31,0x53, 0x2a,0x15,0x15,0x3f, 
+       0x08,0x04,0x04,0x0c, 0x95,0xc7,0xc7,0x52, 0x46,0x23,0x23,0x65, 0x9d,0xc3,0xc3,0x5e, 
+       0x30,0x18,0x18,0x28, 0x37,0x96,0x96,0xa1, 0x0a,0x05,0x05,0x0f, 0x2f,0x9a,0x9a,0xb5, 
+       0x0e,0x07,0x07,0x09, 0x24,0x12,0x12,0x36, 0x1b,0x80,0x80,0x9b, 0xdf,0xe2,0xe2,0x3d, 
+       0xcd,0xeb,0xeb,0x26, 0x4e,0x27,0x27,0x69, 0x7f,0xb2,0xb2,0xcd, 0xea,0x75,0x75,0x9f, 
+       0x12,0x09,0x09,0x1b, 0x1d,0x83,0x83,0x9e, 0x58,0x2c,0x2c,0x74, 0x34,0x1a,0x1a,0x2e, 
+       0x36,0x1b,0x1b,0x2d, 0xdc,0x6e,0x6e,0xb2, 0xb4,0x5a,0x5a,0xee, 0x5b,0xa0,0xa0,0xfb, 
+       0xa4,0x52,0x52,0xf6, 0x76,0x3b,0x3b,0x4d, 0xb7,0xd6,0xd6,0x61, 0x7d,0xb3,0xb3,0xce, 
+       0x52,0x29,0x29,0x7b, 0xdd,0xe3,0xe3,0x3e, 0x5e,0x2f,0x2f,0x71, 0x13,0x84,0x84,0x97, 
+       0xa6,0x53,0x53,0xf5, 0xb9,0xd1,0xd1,0x68, 0x00,0x00,0x00,0x00, 0xc1,0xed,0xed,0x2c, 
+       0x40,0x20,0x20,0x60, 0xe3,0xfc,0xfc,0x1f, 0x79,0xb1,0xb1,0xc8, 0xb6,0x5b,0x5b,0xed, 
+       0xd4,0x6a,0x6a,0xbe, 0x8d,0xcb,0xcb,0x46, 0x67,0xbe,0xbe,0xd9, 0x72,0x39,0x39,0x4b, 
+       0x94,0x4a,0x4a,0xde, 0x98,0x4c,0x4c,0xd4, 0xb0,0x58,0x58,0xe8, 0x85,0xcf,0xcf,0x4a, 
+       0xbb,0xd0,0xd0,0x6b, 0xc5,0xef,0xef,0x2a, 0x4f,0xaa,0xaa,0xe5, 0xed,0xfb,0xfb,0x16, 
+       0x86,0x43,0x43,0xc5, 0x9a,0x4d,0x4d,0xd7, 0x66,0x33,0x33,0x55, 0x11,0x85,0x85,0x94, 
+       0x8a,0x45,0x45,0xcf, 0xe9,0xf9,0xf9,0x10, 0x04,0x02,0x02,0x06, 0xfe,0x7f,0x7f,0x81, 
+       0xa0,0x50,0x50,0xf0, 0x78,0x3c,0x3c,0x44, 0x25,0x9f,0x9f,0xba, 0x4b,0xa8,0xa8,0xe3, 
+       0xa2,0x51,0x51,0xf3, 0x5d,0xa3,0xa3,0xfe, 0x80,0x40,0x40,0xc0, 0x05,0x8f,0x8f,0x8a, 
+       0x3f,0x92,0x92,0xad, 0x21,0x9d,0x9d,0xbc, 0x70,0x38,0x38,0x48, 0xf1,0xf5,0xf5,0x04, 
+       0x63,0xbc,0xbc,0xdf, 0x77,0xb6,0xb6,0xc1, 0xaf,0xda,0xda,0x75, 0x42,0x21,0x21,0x63, 
+       0x20,0x10,0x10,0x30, 0xe5,0xff,0xff,0x1a, 0xfd,0xf3,0xf3,0x0e, 0xbf,0xd2,0xd2,0x6d, 
+       0x81,0xcd,0xcd,0x4c, 0x18,0x0c,0x0c,0x14, 0x26,0x13,0x13,0x35, 0xc3,0xec,0xec,0x2f, 
+       0xbe,0x5f,0x5f,0xe1, 0x35,0x97,0x97,0xa2, 0x88,0x44,0x44,0xcc, 0x2e,0x17,0x17,0x39, 
+       0x93,0xc4,0xc4,0x57, 0x55,0xa7,0xa7,0xf2, 0xfc,0x7e,0x7e,0x82, 0x7a,0x3d,0x3d,0x47, 
+       0xc8,0x64,0x64,0xac, 0xba,0x5d,0x5d,0xe7, 0x32,0x19,0x19,0x2b, 0xe6,0x73,0x73,0x95, 
+       0xc0,0x60,0x60,0xa0, 0x19,0x81,0x81,0x98, 0x9e,0x4f,0x4f,0xd1, 0xa3,0xdc,0xdc,0x7f, 
+       0x44,0x22,0x22,0x66, 0x54,0x2a,0x2a,0x7e, 0x3b,0x90,0x90,0xab, 0x0b,0x88,0x88,0x83, 
+       0x8c,0x46,0x46,0xca, 0xc7,0xee,0xee,0x29, 0x6b,0xb8,0xb8,0xd3, 0x28,0x14,0x14,0x3c, 
+       0xa7,0xde,0xde,0x79, 0xbc,0x5e,0x5e,0xe2, 0x16,0x0b,0x0b,0x1d, 0xad,0xdb,0xdb,0x76, 
+       0xdb,0xe0,0xe0,0x3b, 0x64,0x32,0x32,0x56, 0x74,0x3a,0x3a,0x4e, 0x14,0x0a,0x0a,0x1e, 
+       0x92,0x49,0x49,0xdb, 0x0c,0x06,0x06,0x0a, 0x48,0x24,0x24,0x6c, 0xb8,0x5c,0x5c,0xe4, 
+       0x9f,0xc2,0xc2,0x5d, 0xbd,0xd3,0xd3,0x6e, 0x43,0xac,0xac,0xef, 0xc4,0x62,0x62,0xa6, 
+       0x39,0x91,0x91,0xa8, 0x31,0x95,0x95,0xa4, 0xd3,0xe4,0xe4,0x37, 0xf2,0x79,0x79,0x8b, 
+       0xd5,0xe7,0xe7,0x32, 0x8b,0xc8,0xc8,0x43, 0x6e,0x37,0x37,0x59, 0xda,0x6d,0x6d,0xb7, 
+       0x01,0x8d,0x8d,0x8c, 0xb1,0xd5,0xd5,0x64, 0x9c,0x4e,0x4e,0xd2, 0x49,0xa9,0xa9,0xe0, 
+       0xd8,0x6c,0x6c,0xb4, 0xac,0x56,0x56,0xfa, 0xf3,0xf4,0xf4,0x07, 0xcf,0xea,0xea,0x25, 
+       0xca,0x65,0x65,0xaf, 0xf4,0x7a,0x7a,0x8e, 0x47,0xae,0xae,0xe9, 0x10,0x08,0x08,0x18, 
+       0x6f,0xba,0xba,0xd5, 0xf0,0x78,0x78,0x88, 0x4a,0x25,0x25,0x6f, 0x5c,0x2e,0x2e,0x72, 
+       0x38,0x1c,0x1c,0x24, 0x57,0xa6,0xa6,0xf1, 0x73,0xb4,0xb4,0xc7, 0x97,0xc6,0xc6,0x51, 
+       0xcb,0xe8,0xe8,0x23, 0xa1,0xdd,0xdd,0x7c, 0xe8,0x74,0x74,0x9c, 0x3e,0x1f,0x1f,0x21, 
+       0x96,0x4b,0x4b,0xdd, 0x61,0xbd,0xbd,0xdc, 0x0d,0x8b,0x8b,0x86, 0x0f,0x8a,0x8a,0x85, 
+       0xe0,0x70,0x70,0x90, 0x7c,0x3e,0x3e,0x42, 0x71,0xb5,0xb5,0xc4, 0xcc,0x66,0x66,0xaa, 
+       0x90,0x48,0x48,0xd8, 0x06,0x03,0x03,0x05, 0xf7,0xf6,0xf6,0x01, 0x1c,0x0e,0x0e,0x12, 
+       0xc2,0x61,0x61,0xa3, 0x6a,0x35,0x35,0x5f, 0xae,0x57,0x57,0xf9, 0x69,0xb9,0xb9,0xd0, 
+       0x17,0x86,0x86,0x91, 0x99,0xc1,0xc1,0x58, 0x3a,0x1d,0x1d,0x27, 0x27,0x9e,0x9e,0xb9, 
+       0xd9,0xe1,0xe1,0x38, 0xeb,0xf8,0xf8,0x13, 0x2b,0x98,0x98,0xb3, 0x22,0x11,0x11,0x33, 
+       0xd2,0x69,0x69,0xbb, 0xa9,0xd9,0xd9,0x70, 0x07,0x8e,0x8e,0x89, 0x33,0x94,0x94,0xa7, 
+       0x2d,0x9b,0x9b,0xb6, 0x3c,0x1e,0x1e,0x22, 0x15,0x87,0x87,0x92, 0xc9,0xe9,0xe9,0x20, 
+       0x87,0xce,0xce,0x49, 0xaa,0x55,0x55,0xff, 0x50,0x28,0x28,0x78, 0xa5,0xdf,0xdf,0x7a, 
+       0x03,0x8c,0x8c,0x8f, 0x59,0xa1,0xa1,0xf8, 0x09,0x89,0x89,0x80, 0x1a,0x0d,0x0d,0x17, 
+       0x65,0xbf,0xbf,0xda, 0xd7,0xe6,0xe6,0x31, 0x84,0x42,0x42,0xc6, 0xd0,0x68,0x68,0xb8, 
+       0x82,0x41,0x41,0xc3, 0x29,0x99,0x99,0xb0, 0x5a,0x2d,0x2d,0x77, 0x1e,0x0f,0x0f,0x11, 
+       0x7b,0xb0,0xb0,0xcb, 0xa8,0x54,0x54,0xfc, 0x6d,0xbb,0xbb,0xd6, 0x2c,0x16,0x16,0x3a
+};
+       
+static uint8_t T2[256][4]=
+{
+       0xa5,0xc6,0x63,0x63, 0x84,0xf8,0x7c,0x7c, 0x99,0xee,0x77,0x77, 0x8d,0xf6,0x7b,0x7b, 
+       0x0d,0xff,0xf2,0xf2, 0xbd,0xd6,0x6b,0x6b, 0xb1,0xde,0x6f,0x6f, 0x54,0x91,0xc5,0xc5, 
+       0x50,0x60,0x30,0x30, 0x03,0x02,0x01,0x01, 0xa9,0xce,0x67,0x67, 0x7d,0x56,0x2b,0x2b, 
+       0x19,0xe7,0xfe,0xfe, 0x62,0xb5,0xd7,0xd7, 0xe6,0x4d,0xab,0xab, 0x9a,0xec,0x76,0x76, 
+       0x45,0x8f,0xca,0xca, 0x9d,0x1f,0x82,0x82, 0x40,0x89,0xc9,0xc9, 0x87,0xfa,0x7d,0x7d, 
+       0x15,0xef,0xfa,0xfa, 0xeb,0xb2,0x59,0x59, 0xc9,0x8e,0x47,0x47, 0x0b,0xfb,0xf0,0xf0, 
+       0xec,0x41,0xad,0xad, 0x67,0xb3,0xd4,0xd4, 0xfd,0x5f,0xa2,0xa2, 0xea,0x45,0xaf,0xaf, 
+       0xbf,0x23,0x9c,0x9c, 0xf7,0x53,0xa4,0xa4, 0x96,0xe4,0x72,0x72, 0x5b,0x9b,0xc0,0xc0, 
+       0xc2,0x75,0xb7,0xb7, 0x1c,0xe1,0xfd,0xfd, 0xae,0x3d,0x93,0x93, 0x6a,0x4c,0x26,0x26, 
+       0x5a,0x6c,0x36,0x36, 0x41,0x7e,0x3f,0x3f, 0x02,0xf5,0xf7,0xf7, 0x4f,0x83,0xcc,0xcc, 
+       0x5c,0x68,0x34,0x34, 0xf4,0x51,0xa5,0xa5, 0x34,0xd1,0xe5,0xe5, 0x08,0xf9,0xf1,0xf1, 
+       0x93,0xe2,0x71,0x71, 0x73,0xab,0xd8,0xd8, 0x53,0x62,0x31,0x31, 0x3f,0x2a,0x15,0x15, 
+       0x0c,0x08,0x04,0x04, 0x52,0x95,0xc7,0xc7, 0x65,0x46,0x23,0x23, 0x5e,0x9d,0xc3,0xc3, 
+       0x28,0x30,0x18,0x18, 0xa1,0x37,0x96,0x96, 0x0f,0x0a,0x05,0x05, 0xb5,0x2f,0x9a,0x9a, 
+       0x09,0x0e,0x07,0x07, 0x36,0x24,0x12,0x12, 0x9b,0x1b,0x80,0x80, 0x3d,0xdf,0xe2,0xe2, 
+       0x26,0xcd,0xeb,0xeb, 0x69,0x4e,0x27,0x27, 0xcd,0x7f,0xb2,0xb2, 0x9f,0xea,0x75,0x75, 
+       0x1b,0x12,0x09,0x09, 0x9e,0x1d,0x83,0x83, 0x74,0x58,0x2c,0x2c, 0x2e,0x34,0x1a,0x1a, 
+       0x2d,0x36,0x1b,0x1b, 0xb2,0xdc,0x6e,0x6e, 0xee,0xb4,0x5a,0x5a, 0xfb,0x5b,0xa0,0xa0, 
+       0xf6,0xa4,0x52,0x52, 0x4d,0x76,0x3b,0x3b, 0x61,0xb7,0xd6,0xd6, 0xce,0x7d,0xb3,0xb3, 
+       0x7b,0x52,0x29,0x29, 0x3e,0xdd,0xe3,0xe3, 0x71,0x5e,0x2f,0x2f, 0x97,0x13,0x84,0x84, 
+       0xf5,0xa6,0x53,0x53, 0x68,0xb9,0xd1,0xd1, 0x00,0x00,0x00,0x00, 0x2c,0xc1,0xed,0xed, 
+       0x60,0x40,0x20,0x20, 0x1f,0xe3,0xfc,0xfc, 0xc8,0x79,0xb1,0xb1, 0xed,0xb6,0x5b,0x5b, 
+       0xbe,0xd4,0x6a,0x6a, 0x46,0x8d,0xcb,0xcb, 0xd9,0x67,0xbe,0xbe, 0x4b,0x72,0x39,0x39, 
+       0xde,0x94,0x4a,0x4a, 0xd4,0x98,0x4c,0x4c, 0xe8,0xb0,0x58,0x58, 0x4a,0x85,0xcf,0xcf, 
+       0x6b,0xbb,0xd0,0xd0, 0x2a,0xc5,0xef,0xef, 0xe5,0x4f,0xaa,0xaa, 0x16,0xed,0xfb,0xfb, 
+       0xc5,0x86,0x43,0x43, 0xd7,0x9a,0x4d,0x4d, 0x55,0x66,0x33,0x33, 0x94,0x11,0x85,0x85, 
+       0xcf,0x8a,0x45,0x45, 0x10,0xe9,0xf9,0xf9, 0x06,0x04,0x02,0x02, 0x81,0xfe,0x7f,0x7f, 
+       0xf0,0xa0,0x50,0x50, 0x44,0x78,0x3c,0x3c, 0xba,0x25,0x9f,0x9f, 0xe3,0x4b,0xa8,0xa8, 
+       0xf3,0xa2,0x51,0x51, 0xfe,0x5d,0xa3,0xa3, 0xc0,0x80,0x40,0x40, 0x8a,0x05,0x8f,0x8f, 
+       0xad,0x3f,0x92,0x92, 0xbc,0x21,0x9d,0x9d, 0x48,0x70,0x38,0x38, 0x04,0xf1,0xf5,0xf5, 
+       0xdf,0x63,0xbc,0xbc, 0xc1,0x77,0xb6,0xb6, 0x75,0xaf,0xda,0xda, 0x63,0x42,0x21,0x21, 
+       0x30,0x20,0x10,0x10, 0x1a,0xe5,0xff,0xff, 0x0e,0xfd,0xf3,0xf3, 0x6d,0xbf,0xd2,0xd2, 
+       0x4c,0x81,0xcd,0xcd, 0x14,0x18,0x0c,0x0c, 0x35,0x26,0x13,0x13, 0x2f,0xc3,0xec,0xec, 
+       0xe1,0xbe,0x5f,0x5f, 0xa2,0x35,0x97,0x97, 0xcc,0x88,0x44,0x44, 0x39,0x2e,0x17,0x17, 
+       0x57,0x93,0xc4,0xc4, 0xf2,0x55,0xa7,0xa7, 0x82,0xfc,0x7e,0x7e, 0x47,0x7a,0x3d,0x3d, 
+       0xac,0xc8,0x64,0x64, 0xe7,0xba,0x5d,0x5d, 0x2b,0x32,0x19,0x19, 0x95,0xe6,0x73,0x73, 
+       0xa0,0xc0,0x60,0x60, 0x98,0x19,0x81,0x81, 0xd1,0x9e,0x4f,0x4f, 0x7f,0xa3,0xdc,0xdc, 
+       0x66,0x44,0x22,0x22, 0x7e,0x54,0x2a,0x2a, 0xab,0x3b,0x90,0x90, 0x83,0x0b,0x88,0x88, 
+       0xca,0x8c,0x46,0x46, 0x29,0xc7,0xee,0xee, 0xd3,0x6b,0xb8,0xb8, 0x3c,0x28,0x14,0x14, 
+       0x79,0xa7,0xde,0xde, 0xe2,0xbc,0x5e,0x5e, 0x1d,0x16,0x0b,0x0b, 0x76,0xad,0xdb,0xdb, 
+       0x3b,0xdb,0xe0,0xe0, 0x56,0x64,0x32,0x32, 0x4e,0x74,0x3a,0x3a, 0x1e,0x14,0x0a,0x0a, 
+       0xdb,0x92,0x49,0x49, 0x0a,0x0c,0x06,0x06, 0x6c,0x48,0x24,0x24, 0xe4,0xb8,0x5c,0x5c, 
+       0x5d,0x9f,0xc2,0xc2, 0x6e,0xbd,0xd3,0xd3, 0xef,0x43,0xac,0xac, 0xa6,0xc4,0x62,0x62, 
+       0xa8,0x39,0x91,0x91, 0xa4,0x31,0x95,0x95, 0x37,0xd3,0xe4,0xe4, 0x8b,0xf2,0x79,0x79, 
+       0x32,0xd5,0xe7,0xe7, 0x43,0x8b,0xc8,0xc8, 0x59,0x6e,0x37,0x37, 0xb7,0xda,0x6d,0x6d, 
+       0x8c,0x01,0x8d,0x8d, 0x64,0xb1,0xd5,0xd5, 0xd2,0x9c,0x4e,0x4e, 0xe0,0x49,0xa9,0xa9, 
+       0xb4,0xd8,0x6c,0x6c, 0xfa,0xac,0x56,0x56, 0x07,0xf3,0xf4,0xf4, 0x25,0xcf,0xea,0xea, 
+       0xaf,0xca,0x65,0x65, 0x8e,0xf4,0x7a,0x7a, 0xe9,0x47,0xae,0xae, 0x18,0x10,0x08,0x08, 
+       0xd5,0x6f,0xba,0xba, 0x88,0xf0,0x78,0x78, 0x6f,0x4a,0x25,0x25, 0x72,0x5c,0x2e,0x2e, 
+       0x24,0x38,0x1c,0x1c, 0xf1,0x57,0xa6,0xa6, 0xc7,0x73,0xb4,0xb4, 0x51,0x97,0xc6,0xc6, 
+       0x23,0xcb,0xe8,0xe8, 0x7c,0xa1,0xdd,0xdd, 0x9c,0xe8,0x74,0x74, 0x21,0x3e,0x1f,0x1f, 
+       0xdd,0x96,0x4b,0x4b, 0xdc,0x61,0xbd,0xbd, 0x86,0x0d,0x8b,0x8b, 0x85,0x0f,0x8a,0x8a, 
+       0x90,0xe0,0x70,0x70, 0x42,0x7c,0x3e,0x3e, 0xc4,0x71,0xb5,0xb5, 0xaa,0xcc,0x66,0x66, 
+       0xd8,0x90,0x48,0x48, 0x05,0x06,0x03,0x03, 0x01,0xf7,0xf6,0xf6, 0x12,0x1c,0x0e,0x0e, 
+       0xa3,0xc2,0x61,0x61, 0x5f,0x6a,0x35,0x35, 0xf9,0xae,0x57,0x57, 0xd0,0x69,0xb9,0xb9, 
+       0x91,0x17,0x86,0x86, 0x58,0x99,0xc1,0xc1, 0x27,0x3a,0x1d,0x1d, 0xb9,0x27,0x9e,0x9e, 
+       0x38,0xd9,0xe1,0xe1, 0x13,0xeb,0xf8,0xf8, 0xb3,0x2b,0x98,0x98, 0x33,0x22,0x11,0x11, 
+       0xbb,0xd2,0x69,0x69, 0x70,0xa9,0xd9,0xd9, 0x89,0x07,0x8e,0x8e, 0xa7,0x33,0x94,0x94, 
+       0xb6,0x2d,0x9b,0x9b, 0x22,0x3c,0x1e,0x1e, 0x92,0x15,0x87,0x87, 0x20,0xc9,0xe9,0xe9, 
+       0x49,0x87,0xce,0xce, 0xff,0xaa,0x55,0x55, 0x78,0x50,0x28,0x28, 0x7a,0xa5,0xdf,0xdf, 
+       0x8f,0x03,0x8c,0x8c, 0xf8,0x59,0xa1,0xa1, 0x80,0x09,0x89,0x89, 0x17,0x1a,0x0d,0x0d, 
+       0xda,0x65,0xbf,0xbf, 0x31,0xd7,0xe6,0xe6, 0xc6,0x84,0x42,0x42, 0xb8,0xd0,0x68,0x68, 
+       0xc3,0x82,0x41,0x41, 0xb0,0x29,0x99,0x99, 0x77,0x5a,0x2d,0x2d, 0x11,0x1e,0x0f,0x0f, 
+       0xcb,0x7b,0xb0,0xb0, 0xfc,0xa8,0x54,0x54, 0xd6,0x6d,0xbb,0xbb, 0x3a,0x2c,0x16,0x16
+};
+
+static uint8_t T3[256][4]=
+{
+       0x63,0xa5,0xc6,0x63, 0x7c,0x84,0xf8,0x7c, 0x77,0x99,0xee,0x77, 0x7b,0x8d,0xf6,0x7b, 
+       0xf2,0x0d,0xff,0xf2, 0x6b,0xbd,0xd6,0x6b, 0x6f,0xb1,0xde,0x6f, 0xc5,0x54,0x91,0xc5, 
+       0x30,0x50,0x60,0x30, 0x01,0x03,0x02,0x01, 0x67,0xa9,0xce,0x67, 0x2b,0x7d,0x56,0x2b, 
+       0xfe,0x19,0xe7,0xfe, 0xd7,0x62,0xb5,0xd7, 0xab,0xe6,0x4d,0xab, 0x76,0x9a,0xec,0x76, 
+       0xca,0x45,0x8f,0xca, 0x82,0x9d,0x1f,0x82, 0xc9,0x40,0x89,0xc9, 0x7d,0x87,0xfa,0x7d, 
+       0xfa,0x15,0xef,0xfa, 0x59,0xeb,0xb2,0x59, 0x47,0xc9,0x8e,0x47, 0xf0,0x0b,0xfb,0xf0, 
+       0xad,0xec,0x41,0xad, 0xd4,0x67,0xb3,0xd4, 0xa2,0xfd,0x5f,0xa2, 0xaf,0xea,0x45,0xaf, 
+       0x9c,0xbf,0x23,0x9c, 0xa4,0xf7,0x53,0xa4, 0x72,0x96,0xe4,0x72, 0xc0,0x5b,0x9b,0xc0, 
+       0xb7,0xc2,0x75,0xb7, 0xfd,0x1c,0xe1,0xfd, 0x93,0xae,0x3d,0x93, 0x26,0x6a,0x4c,0x26, 
+       0x36,0x5a,0x6c,0x36, 0x3f,0x41,0x7e,0x3f, 0xf7,0x02,0xf5,0xf7, 0xcc,0x4f,0x83,0xcc, 
+       0x34,0x5c,0x68,0x34, 0xa5,0xf4,0x51,0xa5, 0xe5,0x34,0xd1,0xe5, 0xf1,0x08,0xf9,0xf1, 
+       0x71,0x93,0xe2,0x71, 0xd8,0x73,0xab,0xd8, 0x31,0x53,0x62,0x31, 0x15,0x3f,0x2a,0x15, 
+       0x04,0x0c,0x08,0x04, 0xc7,0x52,0x95,0xc7, 0x23,0x65,0x46,0x23, 0xc3,0x5e,0x9d,0xc3, 
+       0x18,0x28,0x30,0x18, 0x96,0xa1,0x37,0x96, 0x05,0x0f,0x0a,0x05, 0x9a,0xb5,0x2f,0x9a, 
+       0x07,0x09,0x0e,0x07, 0x12,0x36,0x24,0x12, 0x80,0x9b,0x1b,0x80, 0xe2,0x3d,0xdf,0xe2, 
+       0xeb,0x26,0xcd,0xeb, 0x27,0x69,0x4e,0x27, 0xb2,0xcd,0x7f,0xb2, 0x75,0x9f,0xea,0x75, 
+       0x09,0x1b,0x12,0x09, 0x83,0x9e,0x1d,0x83, 0x2c,0x74,0x58,0x2c, 0x1a,0x2e,0x34,0x1a, 
+       0x1b,0x2d,0x36,0x1b, 0x6e,0xb2,0xdc,0x6e, 0x5a,0xee,0xb4,0x5a, 0xa0,0xfb,0x5b,0xa0, 
+       0x52,0xf6,0xa4,0x52, 0x3b,0x4d,0x76,0x3b, 0xd6,0x61,0xb7,0xd6, 0xb3,0xce,0x7d,0xb3, 
+       0x29,0x7b,0x52,0x29, 0xe3,0x3e,0xdd,0xe3, 0x2f,0x71,0x5e,0x2f, 0x84,0x97,0x13,0x84, 
+       0x53,0xf5,0xa6,0x53, 0xd1,0x68,0xb9,0xd1, 0x00,0x00,0x00,0x00, 0xed,0x2c,0xc1,0xed, 
+       0x20,0x60,0x40,0x20, 0xfc,0x1f,0xe3,0xfc, 0xb1,0xc8,0x79,0xb1, 0x5b,0xed,0xb6,0x5b, 
+       0x6a,0xbe,0xd4,0x6a, 0xcb,0x46,0x8d,0xcb, 0xbe,0xd9,0x67,0xbe, 0x39,0x4b,0x72,0x39, 
+       0x4a,0xde,0x94,0x4a, 0x4c,0xd4,0x98,0x4c, 0x58,0xe8,0xb0,0x58, 0xcf,0x4a,0x85,0xcf, 
+       0xd0,0x6b,0xbb,0xd0, 0xef,0x2a,0xc5,0xef, 0xaa,0xe5,0x4f,0xaa, 0xfb,0x16,0xed,0xfb, 
+       0x43,0xc5,0x86,0x43, 0x4d,0xd7,0x9a,0x4d, 0x33,0x55,0x66,0x33, 0x85,0x94,0x11,0x85, 
+       0x45,0xcf,0x8a,0x45, 0xf9,0x10,0xe9,0xf9, 0x02,0x06,0x04,0x02, 0x7f,0x81,0xfe,0x7f, 
+       0x50,0xf0,0xa0,0x50, 0x3c,0x44,0x78,0x3c, 0x9f,0xba,0x25,0x9f, 0xa8,0xe3,0x4b,0xa8, 
+       0x51,0xf3,0xa2,0x51, 0xa3,0xfe,0x5d,0xa3, 0x40,0xc0,0x80,0x40, 0x8f,0x8a,0x05,0x8f, 
+       0x92,0xad,0x3f,0x92, 0x9d,0xbc,0x21,0x9d, 0x38,0x48,0x70,0x38, 0xf5,0x04,0xf1,0xf5, 
+       0xbc,0xdf,0x63,0xbc, 0xb6,0xc1,0x77,0xb6, 0xda,0x75,0xaf,0xda, 0x21,0x63,0x42,0x21, 
+       0x10,0x30,0x20,0x10, 0xff,0x1a,0xe5,0xff, 0xf3,0x0e,0xfd,0xf3, 0xd2,0x6d,0xbf,0xd2, 
+       0xcd,0x4c,0x81,0xcd, 0x0c,0x14,0x18,0x0c, 0x13,0x35,0x26,0x13, 0xec,0x2f,0xc3,0xec, 
+       0x5f,0xe1,0xbe,0x5f, 0x97,0xa2,0x35,0x97, 0x44,0xcc,0x88,0x44, 0x17,0x39,0x2e,0x17, 
+       0xc4,0x57,0x93,0xc4, 0xa7,0xf2,0x55,0xa7, 0x7e,0x82,0xfc,0x7e, 0x3d,0x47,0x7a,0x3d, 
+       0x64,0xac,0xc8,0x64, 0x5d,0xe7,0xba,0x5d, 0x19,0x2b,0x32,0x19, 0x73,0x95,0xe6,0x73, 
+       0x60,0xa0,0xc0,0x60, 0x81,0x98,0x19,0x81, 0x4f,0xd1,0x9e,0x4f, 0xdc,0x7f,0xa3,0xdc, 
+       0x22,0x66,0x44,0x22, 0x2a,0x7e,0x54,0x2a, 0x90,0xab,0x3b,0x90, 0x88,0x83,0x0b,0x88, 
+       0x46,0xca,0x8c,0x46, 0xee,0x29,0xc7,0xee, 0xb8,0xd3,0x6b,0xb8, 0x14,0x3c,0x28,0x14, 
+       0xde,0x79,0xa7,0xde, 0x5e,0xe2,0xbc,0x5e, 0x0b,0x1d,0x16,0x0b, 0xdb,0x76,0xad,0xdb, 
+       0xe0,0x3b,0xdb,0xe0, 0x32,0x56,0x64,0x32, 0x3a,0x4e,0x74,0x3a, 0x0a,0x1e,0x14,0x0a, 
+       0x49,0xdb,0x92,0x49, 0x06,0x0a,0x0c,0x06, 0x24,0x6c,0x48,0x24, 0x5c,0xe4,0xb8,0x5c, 
+       0xc2,0x5d,0x9f,0xc2, 0xd3,0x6e,0xbd,0xd3, 0xac,0xef,0x43,0xac, 0x62,0xa6,0xc4,0x62, 
+       0x91,0xa8,0x39,0x91, 0x95,0xa4,0x31,0x95, 0xe4,0x37,0xd3,0xe4, 0x79,0x8b,0xf2,0x79, 
+       0xe7,0x32,0xd5,0xe7, 0xc8,0x43,0x8b,0xc8, 0x37,0x59,0x6e,0x37, 0x6d,0xb7,0xda,0x6d, 
+       0x8d,0x8c,0x01,0x8d, 0xd5,0x64,0xb1,0xd5, 0x4e,0xd2,0x9c,0x4e, 0xa9,0xe0,0x49,0xa9, 
+       0x6c,0xb4,0xd8,0x6c, 0x56,0xfa,0xac,0x56, 0xf4,0x07,0xf3,0xf4, 0xea,0x25,0xcf,0xea, 
+       0x65,0xaf,0xca,0x65, 0x7a,0x8e,0xf4,0x7a, 0xae,0xe9,0x47,0xae, 0x08,0x18,0x10,0x08, 
+       0xba,0xd5,0x6f,0xba, 0x78,0x88,0xf0,0x78, 0x25,0x6f,0x4a,0x25, 0x2e,0x72,0x5c,0x2e, 
+       0x1c,0x24,0x38,0x1c, 0xa6,0xf1,0x57,0xa6, 0xb4,0xc7,0x73,0xb4, 0xc6,0x51,0x97,0xc6, 
+       0xe8,0x23,0xcb,0xe8, 0xdd,0x7c,0xa1,0xdd, 0x74,0x9c,0xe8,0x74, 0x1f,0x21,0x3e,0x1f, 
+       0x4b,0xdd,0x96,0x4b, 0xbd,0xdc,0x61,0xbd, 0x8b,0x86,0x0d,0x8b, 0x8a,0x85,0x0f,0x8a, 
+       0x70,0x90,0xe0,0x70, 0x3e,0x42,0x7c,0x3e, 0xb5,0xc4,0x71,0xb5, 0x66,0xaa,0xcc,0x66, 
+       0x48,0xd8,0x90,0x48, 0x03,0x05,0x06,0x03, 0xf6,0x01,0xf7,0xf6, 0x0e,0x12,0x1c,0x0e, 
+       0x61,0xa3,0xc2,0x61, 0x35,0x5f,0x6a,0x35, 0x57,0xf9,0xae,0x57, 0xb9,0xd0,0x69,0xb9, 
+       0x86,0x91,0x17,0x86, 0xc1,0x58,0x99,0xc1, 0x1d,0x27,0x3a,0x1d, 0x9e,0xb9,0x27,0x9e, 
+       0xe1,0x38,0xd9,0xe1, 0xf8,0x13,0xeb,0xf8, 0x98,0xb3,0x2b,0x98, 0x11,0x33,0x22,0x11, 
+       0x69,0xbb,0xd2,0x69, 0xd9,0x70,0xa9,0xd9, 0x8e,0x89,0x07,0x8e, 0x94,0xa7,0x33,0x94, 
+       0x9b,0xb6,0x2d,0x9b, 0x1e,0x22,0x3c,0x1e, 0x87,0x92,0x15,0x87, 0xe9,0x20,0xc9,0xe9, 
+       0xce,0x49,0x87,0xce, 0x55,0xff,0xaa,0x55, 0x28,0x78,0x50,0x28, 0xdf,0x7a,0xa5,0xdf, 
+       0x8c,0x8f,0x03,0x8c, 0xa1,0xf8,0x59,0xa1, 0x89,0x80,0x09,0x89, 0x0d,0x17,0x1a,0x0d, 
+       0xbf,0xda,0x65,0xbf, 0xe6,0x31,0xd7,0xe6, 0x42,0xc6,0x84,0x42, 0x68,0xb8,0xd0,0x68, 
+       0x41,0xc3,0x82,0x41, 0x99,0xb0,0x29,0x99, 0x2d,0x77,0x5a,0x2d, 0x0f,0x11,0x1e,0x0f, 
+       0xb0,0xcb,0x7b,0xb0, 0x54,0xfc,0xa8,0x54, 0xbb,0xd6,0x6d,0xbb, 0x16,0x3a,0x2c,0x16
+};
+
+static uint8_t T4[256][4]=
+{
+       0x63,0x63,0xa5,0xc6, 0x7c,0x7c,0x84,0xf8, 0x77,0x77,0x99,0xee, 0x7b,0x7b,0x8d,0xf6, 
+       0xf2,0xf2,0x0d,0xff, 0x6b,0x6b,0xbd,0xd6, 0x6f,0x6f,0xb1,0xde, 0xc5,0xc5,0x54,0x91, 
+       0x30,0x30,0x50,0x60, 0x01,0x01,0x03,0x02, 0x67,0x67,0xa9,0xce, 0x2b,0x2b,0x7d,0x56, 
+       0xfe,0xfe,0x19,0xe7, 0xd7,0xd7,0x62,0xb5, 0xab,0xab,0xe6,0x4d, 0x76,0x76,0x9a,0xec, 
+       0xca,0xca,0x45,0x8f, 0x82,0x82,0x9d,0x1f, 0xc9,0xc9,0x40,0x89, 0x7d,0x7d,0x87,0xfa, 
+       0xfa,0xfa,0x15,0xef, 0x59,0x59,0xeb,0xb2, 0x47,0x47,0xc9,0x8e, 0xf0,0xf0,0x0b,0xfb, 
+       0xad,0xad,0xec,0x41, 0xd4,0xd4,0x67,0xb3, 0xa2,0xa2,0xfd,0x5f, 0xaf,0xaf,0xea,0x45, 
+       0x9c,0x9c,0xbf,0x23, 0xa4,0xa4,0xf7,0x53, 0x72,0x72,0x96,0xe4, 0xc0,0xc0,0x5b,0x9b, 
+       0xb7,0xb7,0xc2,0x75, 0xfd,0xfd,0x1c,0xe1, 0x93,0x93,0xae,0x3d, 0x26,0x26,0x6a,0x4c, 
+       0x36,0x36,0x5a,0x6c, 0x3f,0x3f,0x41,0x7e, 0xf7,0xf7,0x02,0xf5, 0xcc,0xcc,0x4f,0x83, 
+       0x34,0x34,0x5c,0x68, 0xa5,0xa5,0xf4,0x51, 0xe5,0xe5,0x34,0xd1, 0xf1,0xf1,0x08,0xf9, 
+       0x71,0x71,0x93,0xe2, 0xd8,0xd8,0x73,0xab, 0x31,0x31,0x53,0x62, 0x15,0x15,0x3f,0x2a, 
+       0x04,0x04,0x0c,0x08, 0xc7,0xc7,0x52,0x95, 0x23,0x23,0x65,0x46, 0xc3,0xc3,0x5e,0x9d, 
+       0x18,0x18,0x28,0x30, 0x96,0x96,0xa1,0x37, 0x05,0x05,0x0f,0x0a, 0x9a,0x9a,0xb5,0x2f, 
+       0x07,0x07,0x09,0x0e, 0x12,0x12,0x36,0x24, 0x80,0x80,0x9b,0x1b, 0xe2,0xe2,0x3d,0xdf, 
+       0xeb,0xeb,0x26,0xcd, 0x27,0x27,0x69,0x4e, 0xb2,0xb2,0xcd,0x7f, 0x75,0x75,0x9f,0xea, 
+       0x09,0x09,0x1b,0x12, 0x83,0x83,0x9e,0x1d, 0x2c,0x2c,0x74,0x58, 0x1a,0x1a,0x2e,0x34, 
+       0x1b,0x1b,0x2d,0x36, 0x6e,0x6e,0xb2,0xdc, 0x5a,0x5a,0xee,0xb4, 0xa0,0xa0,0xfb,0x5b, 
+       0x52,0x52,0xf6,0xa4, 0x3b,0x3b,0x4d,0x76, 0xd6,0xd6,0x61,0xb7, 0xb3,0xb3,0xce,0x7d, 
+       0x29,0x29,0x7b,0x52, 0xe3,0xe3,0x3e,0xdd, 0x2f,0x2f,0x71,0x5e, 0x84,0x84,0x97,0x13, 
+       0x53,0x53,0xf5,0xa6, 0xd1,0xd1,0x68,0xb9, 0x00,0x00,0x00,0x00, 0xed,0xed,0x2c,0xc1, 
+       0x20,0x20,0x60,0x40, 0xfc,0xfc,0x1f,0xe3, 0xb1,0xb1,0xc8,0x79, 0x5b,0x5b,0xed,0xb6, 
+       0x6a,0x6a,0xbe,0xd4, 0xcb,0xcb,0x46,0x8d, 0xbe,0xbe,0xd9,0x67, 0x39,0x39,0x4b,0x72, 
+       0x4a,0x4a,0xde,0x94, 0x4c,0x4c,0xd4,0x98, 0x58,0x58,0xe8,0xb0, 0xcf,0xcf,0x4a,0x85, 
+       0xd0,0xd0,0x6b,0xbb, 0xef,0xef,0x2a,0xc5, 0xaa,0xaa,0xe5,0x4f, 0xfb,0xfb,0x16,0xed, 
+       0x43,0x43,0xc5,0x86, 0x4d,0x4d,0xd7,0x9a, 0x33,0x33,0x55,0x66, 0x85,0x85,0x94,0x11, 
+       0x45,0x45,0xcf,0x8a, 0xf9,0xf9,0x10,0xe9, 0x02,0x02,0x06,0x04, 0x7f,0x7f,0x81,0xfe, 
+       0x50,0x50,0xf0,0xa0, 0x3c,0x3c,0x44,0x78, 0x9f,0x9f,0xba,0x25, 0xa8,0xa8,0xe3,0x4b, 
+       0x51,0x51,0xf3,0xa2, 0xa3,0xa3,0xfe,0x5d, 0x40,0x40,0xc0,0x80, 0x8f,0x8f,0x8a,0x05, 
+       0x92,0x92,0xad,0x3f, 0x9d,0x9d,0xbc,0x21, 0x38,0x38,0x48,0x70, 0xf5,0xf5,0x04,0xf1, 
+       0xbc,0xbc,0xdf,0x63, 0xb6,0xb6,0xc1,0x77, 0xda,0xda,0x75,0xaf, 0x21,0x21,0x63,0x42, 
+       0x10,0x10,0x30,0x20, 0xff,0xff,0x1a,0xe5, 0xf3,0xf3,0x0e,0xfd, 0xd2,0xd2,0x6d,0xbf, 
+       0xcd,0xcd,0x4c,0x81, 0x0c,0x0c,0x14,0x18, 0x13,0x13,0x35,0x26, 0xec,0xec,0x2f,0xc3, 
+       0x5f,0x5f,0xe1,0xbe, 0x97,0x97,0xa2,0x35, 0x44,0x44,0xcc,0x88, 0x17,0x17,0x39,0x2e, 
+       0xc4,0xc4,0x57,0x93, 0xa7,0xa7,0xf2,0x55, 0x7e,0x7e,0x82,0xfc, 0x3d,0x3d,0x47,0x7a, 
+       0x64,0x64,0xac,0xc8, 0x5d,0x5d,0xe7,0xba, 0x19,0x19,0x2b,0x32, 0x73,0x73,0x95,0xe6, 
+       0x60,0x60,0xa0,0xc0, 0x81,0x81,0x98,0x19, 0x4f,0x4f,0xd1,0x9e, 0xdc,0xdc,0x7f,0xa3, 
+       0x22,0x22,0x66,0x44, 0x2a,0x2a,0x7e,0x54, 0x90,0x90,0xab,0x3b, 0x88,0x88,0x83,0x0b, 
+       0x46,0x46,0xca,0x8c, 0xee,0xee,0x29,0xc7, 0xb8,0xb8,0xd3,0x6b, 0x14,0x14,0x3c,0x28, 
+       0xde,0xde,0x79,0xa7, 0x5e,0x5e,0xe2,0xbc, 0x0b,0x0b,0x1d,0x16, 0xdb,0xdb,0x76,0xad, 
+       0xe0,0xe0,0x3b,0xdb, 0x32,0x32,0x56,0x64, 0x3a,0x3a,0x4e,0x74, 0x0a,0x0a,0x1e,0x14, 
+       0x49,0x49,0xdb,0x92, 0x06,0x06,0x0a,0x0c, 0x24,0x24,0x6c,0x48, 0x5c,0x5c,0xe4,0xb8, 
+       0xc2,0xc2,0x5d,0x9f, 0xd3,0xd3,0x6e,0xbd, 0xac,0xac,0xef,0x43, 0x62,0x62,0xa6,0xc4, 
+       0x91,0x91,0xa8,0x39, 0x95,0x95,0xa4,0x31, 0xe4,0xe4,0x37,0xd3, 0x79,0x79,0x8b,0xf2, 
+       0xe7,0xe7,0x32,0xd5, 0xc8,0xc8,0x43,0x8b, 0x37,0x37,0x59,0x6e, 0x6d,0x6d,0xb7,0xda, 
+       0x8d,0x8d,0x8c,0x01, 0xd5,0xd5,0x64,0xb1, 0x4e,0x4e,0xd2,0x9c, 0xa9,0xa9,0xe0,0x49, 
+       0x6c,0x6c,0xb4,0xd8, 0x56,0x56,0xfa,0xac, 0xf4,0xf4,0x07,0xf3, 0xea,0xea,0x25,0xcf, 
+       0x65,0x65,0xaf,0xca, 0x7a,0x7a,0x8e,0xf4, 0xae,0xae,0xe9,0x47, 0x08,0x08,0x18,0x10, 
+       0xba,0xba,0xd5,0x6f, 0x78,0x78,0x88,0xf0, 0x25,0x25,0x6f,0x4a, 0x2e,0x2e,0x72,0x5c, 
+       0x1c,0x1c,0x24,0x38, 0xa6,0xa6,0xf1,0x57, 0xb4,0xb4,0xc7,0x73, 0xc6,0xc6,0x51,0x97, 
+       0xe8,0xe8,0x23,0xcb, 0xdd,0xdd,0x7c,0xa1, 0x74,0x74,0x9c,0xe8, 0x1f,0x1f,0x21,0x3e, 
+       0x4b,0x4b,0xdd,0x96, 0xbd,0xbd,0xdc,0x61, 0x8b,0x8b,0x86,0x0d, 0x8a,0x8a,0x85,0x0f, 
+       0x70,0x70,0x90,0xe0, 0x3e,0x3e,0x42,0x7c, 0xb5,0xb5,0xc4,0x71, 0x66,0x66,0xaa,0xcc, 
+       0x48,0x48,0xd8,0x90, 0x03,0x03,0x05,0x06, 0xf6,0xf6,0x01,0xf7, 0x0e,0x0e,0x12,0x1c, 
+       0x61,0x61,0xa3,0xc2, 0x35,0x35,0x5f,0x6a, 0x57,0x57,0xf9,0xae, 0xb9,0xb9,0xd0,0x69, 
+       0x86,0x86,0x91,0x17, 0xc1,0xc1,0x58,0x99, 0x1d,0x1d,0x27,0x3a, 0x9e,0x9e,0xb9,0x27, 
+       0xe1,0xe1,0x38,0xd9, 0xf8,0xf8,0x13,0xeb, 0x98,0x98,0xb3,0x2b, 0x11,0x11,0x33,0x22, 
+       0x69,0x69,0xbb,0xd2, 0xd9,0xd9,0x70,0xa9, 0x8e,0x8e,0x89,0x07, 0x94,0x94,0xa7,0x33, 
+       0x9b,0x9b,0xb6,0x2d, 0x1e,0x1e,0x22,0x3c, 0x87,0x87,0x92,0x15, 0xe9,0xe9,0x20,0xc9, 
+       0xce,0xce,0x49,0x87, 0x55,0x55,0xff,0xaa, 0x28,0x28,0x78,0x50, 0xdf,0xdf,0x7a,0xa5, 
+       0x8c,0x8c,0x8f,0x03, 0xa1,0xa1,0xf8,0x59, 0x89,0x89,0x80,0x09, 0x0d,0x0d,0x17,0x1a, 
+       0xbf,0xbf,0xda,0x65, 0xe6,0xe6,0x31,0xd7, 0x42,0x42,0xc6,0x84, 0x68,0x68,0xb8,0xd0, 
+       0x41,0x41,0xc3,0x82, 0x99,0x99,0xb0,0x29, 0x2d,0x2d,0x77,0x5a, 0x0f,0x0f,0x11,0x1e, 
+       0xb0,0xb0,0xcb,0x7b, 0x54,0x54,0xfc,0xa8, 0xbb,0xbb,0xd6,0x6d, 0x16,0x16,0x3a,0x2c
+};
+
+static uint8_t T5[256][4]=
+{
+       0x51,0xf4,0xa7,0x50, 0x7e,0x41,0x65,0x53, 0x1a,0x17,0xa4,0xc3, 0x3a,0x27,0x5e,0x96, 
+       0x3b,0xab,0x6b,0xcb, 0x1f,0x9d,0x45,0xf1, 0xac,0xfa,0x58,0xab, 0x4b,0xe3,0x03,0x93, 
+       0x20,0x30,0xfa,0x55, 0xad,0x76,0x6d,0xf6, 0x88,0xcc,0x76,0x91, 0xf5,0x02,0x4c,0x25, 
+       0x4f,0xe5,0xd7,0xfc, 0xc5,0x2a,0xcb,0xd7, 0x26,0x35,0x44,0x80, 0xb5,0x62,0xa3,0x8f, 
+       0xde,0xb1,0x5a,0x49, 0x25,0xba,0x1b,0x67, 0x45,0xea,0x0e,0x98, 0x5d,0xfe,0xc0,0xe1, 
+       0xc3,0x2f,0x75,0x02, 0x81,0x4c,0xf0,0x12, 0x8d,0x46,0x97,0xa3, 0x6b,0xd3,0xf9,0xc6, 
+       0x03,0x8f,0x5f,0xe7, 0x15,0x92,0x9c,0x95, 0xbf,0x6d,0x7a,0xeb, 0x95,0x52,0x59,0xda, 
+       0xd4,0xbe,0x83,0x2d, 0x58,0x74,0x21,0xd3, 0x49,0xe0,0x69,0x29, 0x8e,0xc9,0xc8,0x44, 
+       0x75,0xc2,0x89,0x6a, 0xf4,0x8e,0x79,0x78, 0x99,0x58,0x3e,0x6b, 0x27,0xb9,0x71,0xdd, 
+       0xbe,0xe1,0x4f,0xb6, 0xf0,0x88,0xad,0x17, 0xc9,0x20,0xac,0x66, 0x7d,0xce,0x3a,0xb4, 
+       0x63,0xdf,0x4a,0x18, 0xe5,0x1a,0x31,0x82, 0x97,0x51,0x33,0x60, 0x62,0x53,0x7f,0x45, 
+       0xb1,0x64,0x77,0xe0, 0xbb,0x6b,0xae,0x84, 0xfe,0x81,0xa0,0x1c, 0xf9,0x08,0x2b,0x94, 
+       0x70,0x48,0x68,0x58, 0x8f,0x45,0xfd,0x19, 0x94,0xde,0x6c,0x87, 0x52,0x7b,0xf8,0xb7, 
+       0xab,0x73,0xd3,0x23, 0x72,0x4b,0x02,0xe2, 0xe3,0x1f,0x8f,0x57, 0x66,0x55,0xab,0x2a, 
+       0xb2,0xeb,0x28,0x07, 0x2f,0xb5,0xc2,0x03, 0x86,0xc5,0x7b,0x9a, 0xd3,0x37,0x08,0xa5, 
+       0x30,0x28,0x87,0xf2, 0x23,0xbf,0xa5,0xb2, 0x02,0x03,0x6a,0xba, 0xed,0x16,0x82,0x5c, 
+       0x8a,0xcf,0x1c,0x2b, 0xa7,0x79,0xb4,0x92, 0xf3,0x07,0xf2,0xf0, 0x4e,0x69,0xe2,0xa1, 
+       0x65,0xda,0xf4,0xcd, 0x06,0x05,0xbe,0xd5, 0xd1,0x34,0x62,0x1f, 0xc4,0xa6,0xfe,0x8a, 
+       0x34,0x2e,0x53,0x9d, 0xa2,0xf3,0x55,0xa0, 0x05,0x8a,0xe1,0x32, 0xa4,0xf6,0xeb,0x75, 
+       0x0b,0x83,0xec,0x39, 0x40,0x60,0xef,0xaa, 0x5e,0x71,0x9f,0x06, 0xbd,0x6e,0x10,0x51, 
+       0x3e,0x21,0x8a,0xf9, 0x96,0xdd,0x06,0x3d, 0xdd,0x3e,0x05,0xae, 0x4d,0xe6,0xbd,0x46, 
+       0x91,0x54,0x8d,0xb5, 0x71,0xc4,0x5d,0x05, 0x04,0x06,0xd4,0x6f, 0x60,0x50,0x15,0xff, 
+       0x19,0x98,0xfb,0x24, 0xd6,0xbd,0xe9,0x97, 0x89,0x40,0x43,0xcc, 0x67,0xd9,0x9e,0x77, 
+       0xb0,0xe8,0x42,0xbd, 0x07,0x89,0x8b,0x88, 0xe7,0x19,0x5b,0x38, 0x79,0xc8,0xee,0xdb, 
+       0xa1,0x7c,0x0a,0x47, 0x7c,0x42,0x0f,0xe9, 0xf8,0x84,0x1e,0xc9, 0x00,0x00,0x00,0x00, 
+       0x09,0x80,0x86,0x83, 0x32,0x2b,0xed,0x48, 0x1e,0x11,0x70,0xac, 0x6c,0x5a,0x72,0x4e, 
+       0xfd,0x0e,0xff,0xfb, 0x0f,0x85,0x38,0x56, 0x3d,0xae,0xd5,0x1e, 0x36,0x2d,0x39,0x27, 
+       0x0a,0x0f,0xd9,0x64, 0x68,0x5c,0xa6,0x21, 0x9b,0x5b,0x54,0xd1, 0x24,0x36,0x2e,0x3a, 
+       0x0c,0x0a,0x67,0xb1, 0x93,0x57,0xe7,0x0f, 0xb4,0xee,0x96,0xd2, 0x1b,0x9b,0x91,0x9e, 
+       0x80,0xc0,0xc5,0x4f, 0x61,0xdc,0x20,0xa2, 0x5a,0x77,0x4b,0x69, 0x1c,0x12,0x1a,0x16, 
+       0xe2,0x93,0xba,0x0a, 0xc0,0xa0,0x2a,0xe5, 0x3c,0x22,0xe0,0x43, 0x12,0x1b,0x17,0x1d, 
+       0x0e,0x09,0x0d,0x0b, 0xf2,0x8b,0xc7,0xad, 0x2d,0xb6,0xa8,0xb9, 0x14,0x1e,0xa9,0xc8, 
+       0x57,0xf1,0x19,0x85, 0xaf,0x75,0x07,0x4c, 0xee,0x99,0xdd,0xbb, 0xa3,0x7f,0x60,0xfd, 
+       0xf7,0x01,0x26,0x9f, 0x5c,0x72,0xf5,0xbc, 0x44,0x66,0x3b,0xc5, 0x5b,0xfb,0x7e,0x34, 
+       0x8b,0x43,0x29,0x76, 0xcb,0x23,0xc6,0xdc, 0xb6,0xed,0xfc,0x68, 0xb8,0xe4,0xf1,0x63, 
+       0xd7,0x31,0xdc,0xca, 0x42,0x63,0x85,0x10, 0x13,0x97,0x22,0x40, 0x84,0xc6,0x11,0x20, 
+       0x85,0x4a,0x24,0x7d, 0xd2,0xbb,0x3d,0xf8, 0xae,0xf9,0x32,0x11, 0xc7,0x29,0xa1,0x6d, 
+       0x1d,0x9e,0x2f,0x4b, 0xdc,0xb2,0x30,0xf3, 0x0d,0x86,0x52,0xec, 0x77,0xc1,0xe3,0xd0, 
+       0x2b,0xb3,0x16,0x6c, 0xa9,0x70,0xb9,0x99, 0x11,0x94,0x48,0xfa, 0x47,0xe9,0x64,0x22, 
+       0xa8,0xfc,0x8c,0xc4, 0xa0,0xf0,0x3f,0x1a, 0x56,0x7d,0x2c,0xd8, 0x22,0x33,0x90,0xef, 
+       0x87,0x49,0x4e,0xc7, 0xd9,0x38,0xd1,0xc1, 0x8c,0xca,0xa2,0xfe, 0x98,0xd4,0x0b,0x36, 
+       0xa6,0xf5,0x81,0xcf, 0xa5,0x7a,0xde,0x28, 0xda,0xb7,0x8e,0x26, 0x3f,0xad,0xbf,0xa4, 
+       0x2c,0x3a,0x9d,0xe4, 0x50,0x78,0x92,0x0d, 0x6a,0x5f,0xcc,0x9b, 0x54,0x7e,0x46,0x62, 
+       0xf6,0x8d,0x13,0xc2, 0x90,0xd8,0xb8,0xe8, 0x2e,0x39,0xf7,0x5e, 0x82,0xc3,0xaf,0xf5, 
+       0x9f,0x5d,0x80,0xbe, 0x69,0xd0,0x93,0x7c, 0x6f,0xd5,0x2d,0xa9, 0xcf,0x25,0x12,0xb3, 
+       0xc8,0xac,0x99,0x3b, 0x10,0x18,0x7d,0xa7, 0xe8,0x9c,0x63,0x6e, 0xdb,0x3b,0xbb,0x7b, 
+       0xcd,0x26,0x78,0x09, 0x6e,0x59,0x18,0xf4, 0xec,0x9a,0xb7,0x01, 0x83,0x4f,0x9a,0xa8, 
+       0xe6,0x95,0x6e,0x65, 0xaa,0xff,0xe6,0x7e, 0x21,0xbc,0xcf,0x08, 0xef,0x15,0xe8,0xe6, 
+       0xba,0xe7,0x9b,0xd9, 0x4a,0x6f,0x36,0xce, 0xea,0x9f,0x09,0xd4, 0x29,0xb0,0x7c,0xd6, 
+       0x31,0xa4,0xb2,0xaf, 0x2a,0x3f,0x23,0x31, 0xc6,0xa5,0x94,0x30, 0x35,0xa2,0x66,0xc0, 
+       0x74,0x4e,0xbc,0x37, 0xfc,0x82,0xca,0xa6, 0xe0,0x90,0xd0,0xb0, 0x33,0xa7,0xd8,0x15, 
+       0xf1,0x04,0x98,0x4a, 0x41,0xec,0xda,0xf7, 0x7f,0xcd,0x50,0x0e, 0x17,0x91,0xf6,0x2f, 
+       0x76,0x4d,0xd6,0x8d, 0x43,0xef,0xb0,0x4d, 0xcc,0xaa,0x4d,0x54, 0xe4,0x96,0x04,0xdf, 
+       0x9e,0xd1,0xb5,0xe3, 0x4c,0x6a,0x88,0x1b, 0xc1,0x2c,0x1f,0xb8, 0x46,0x65,0x51,0x7f, 
+       0x9d,0x5e,0xea,0x04, 0x01,0x8c,0x35,0x5d, 0xfa,0x87,0x74,0x73, 0xfb,0x0b,0x41,0x2e, 
+       0xb3,0x67,0x1d,0x5a, 0x92,0xdb,0xd2,0x52, 0xe9,0x10,0x56,0x33, 0x6d,0xd6,0x47,0x13, 
+       0x9a,0xd7,0x61,0x8c, 0x37,0xa1,0x0c,0x7a, 0x59,0xf8,0x14,0x8e, 0xeb,0x13,0x3c,0x89, 
+       0xce,0xa9,0x27,0xee, 0xb7,0x61,0xc9,0x35, 0xe1,0x1c,0xe5,0xed, 0x7a,0x47,0xb1,0x3c, 
+       0x9c,0xd2,0xdf,0x59, 0x55,0xf2,0x73,0x3f, 0x18,0x14,0xce,0x79, 0x73,0xc7,0x37,0xbf, 
+       0x53,0xf7,0xcd,0xea, 0x5f,0xfd,0xaa,0x5b, 0xdf,0x3d,0x6f,0x14, 0x78,0x44,0xdb,0x86, 
+       0xca,0xaf,0xf3,0x81, 0xb9,0x68,0xc4,0x3e, 0x38,0x24,0x34,0x2c, 0xc2,0xa3,0x40,0x5f, 
+       0x16,0x1d,0xc3,0x72, 0xbc,0xe2,0x25,0x0c, 0x28,0x3c,0x49,0x8b, 0xff,0x0d,0x95,0x41, 
+       0x39,0xa8,0x01,0x71, 0x08,0x0c,0xb3,0xde, 0xd8,0xb4,0xe4,0x9c, 0x64,0x56,0xc1,0x90, 
+       0x7b,0xcb,0x84,0x61, 0xd5,0x32,0xb6,0x70, 0x48,0x6c,0x5c,0x74, 0xd0,0xb8,0x57,0x42
+};
+
+static uint8_t T6[256][4]=
+{
+       0x50,0x51,0xf4,0xa7, 0x53,0x7e,0x41,0x65, 0xc3,0x1a,0x17,0xa4, 0x96,0x3a,0x27,0x5e, 
+       0xcb,0x3b,0xab,0x6b, 0xf1,0x1f,0x9d,0x45, 0xab,0xac,0xfa,0x58, 0x93,0x4b,0xe3,0x03, 
+       0x55,0x20,0x30,0xfa, 0xf6,0xad,0x76,0x6d, 0x91,0x88,0xcc,0x76, 0x25,0xf5,0x02,0x4c, 
+       0xfc,0x4f,0xe5,0xd7, 0xd7,0xc5,0x2a,0xcb, 0x80,0x26,0x35,0x44, 0x8f,0xb5,0x62,0xa3, 
+       0x49,0xde,0xb1,0x5a, 0x67,0x25,0xba,0x1b, 0x98,0x45,0xea,0x0e, 0xe1,0x5d,0xfe,0xc0, 
+       0x02,0xc3,0x2f,0x75, 0x12,0x81,0x4c,0xf0, 0xa3,0x8d,0x46,0x97, 0xc6,0x6b,0xd3,0xf9, 
+       0xe7,0x03,0x8f,0x5f, 0x95,0x15,0x92,0x9c, 0xeb,0xbf,0x6d,0x7a, 0xda,0x95,0x52,0x59, 
+       0x2d,0xd4,0xbe,0x83, 0xd3,0x58,0x74,0x21, 0x29,0x49,0xe0,0x69, 0x44,0x8e,0xc9,0xc8, 
+       0x6a,0x75,0xc2,0x89, 0x78,0xf4,0x8e,0x79, 0x6b,0x99,0x58,0x3e, 0xdd,0x27,0xb9,0x71, 
+       0xb6,0xbe,0xe1,0x4f, 0x17,0xf0,0x88,0xad, 0x66,0xc9,0x20,0xac, 0xb4,0x7d,0xce,0x3a, 
+       0x18,0x63,0xdf,0x4a, 0x82,0xe5,0x1a,0x31, 0x60,0x97,0x51,0x33, 0x45,0x62,0x53,0x7f, 
+       0xe0,0xb1,0x64,0x77, 0x84,0xbb,0x6b,0xae, 0x1c,0xfe,0x81,0xa0, 0x94,0xf9,0x08,0x2b, 
+       0x58,0x70,0x48,0x68, 0x19,0x8f,0x45,0xfd, 0x87,0x94,0xde,0x6c, 0xb7,0x52,0x7b,0xf8, 
+       0x23,0xab,0x73,0xd3, 0xe2,0x72,0x4b,0x02, 0x57,0xe3,0x1f,0x8f, 0x2a,0x66,0x55,0xab, 
+       0x07,0xb2,0xeb,0x28, 0x03,0x2f,0xb5,0xc2, 0x9a,0x86,0xc5,0x7b, 0xa5,0xd3,0x37,0x08, 
+       0xf2,0x30,0x28,0x87, 0xb2,0x23,0xbf,0xa5, 0xba,0x02,0x03,0x6a, 0x5c,0xed,0x16,0x82, 
+       0x2b,0x8a,0xcf,0x1c, 0x92,0xa7,0x79,0xb4, 0xf0,0xf3,0x07,0xf2, 0xa1,0x4e,0x69,0xe2, 
+       0xcd,0x65,0xda,0xf4, 0xd5,0x06,0x05,0xbe, 0x1f,0xd1,0x34,0x62, 0x8a,0xc4,0xa6,0xfe, 
+       0x9d,0x34,0x2e,0x53, 0xa0,0xa2,0xf3,0x55, 0x32,0x05,0x8a,0xe1, 0x75,0xa4,0xf6,0xeb, 
+       0x39,0x0b,0x83,0xec, 0xaa,0x40,0x60,0xef, 0x06,0x5e,0x71,0x9f, 0x51,0xbd,0x6e,0x10, 
+       0xf9,0x3e,0x21,0x8a, 0x3d,0x96,0xdd,0x06, 0xae,0xdd,0x3e,0x05, 0x46,0x4d,0xe6,0xbd, 
+       0xb5,0x91,0x54,0x8d, 0x05,0x71,0xc4,0x5d, 0x6f,0x04,0x06,0xd4, 0xff,0x60,0x50,0x15, 
+       0x24,0x19,0x98,0xfb, 0x97,0xd6,0xbd,0xe9, 0xcc,0x89,0x40,0x43, 0x77,0x67,0xd9,0x9e, 
+       0xbd,0xb0,0xe8,0x42, 0x88,0x07,0x89,0x8b, 0x38,0xe7,0x19,0x5b, 0xdb,0x79,0xc8,0xee, 
+       0x47,0xa1,0x7c,0x0a, 0xe9,0x7c,0x42,0x0f, 0xc9,0xf8,0x84,0x1e, 0x00,0x00,0x00,0x00, 
+       0x83,0x09,0x80,0x86, 0x48,0x32,0x2b,0xed, 0xac,0x1e,0x11,0x70, 0x4e,0x6c,0x5a,0x72, 
+       0xfb,0xfd,0x0e,0xff, 0x56,0x0f,0x85,0x38, 0x1e,0x3d,0xae,0xd5, 0x27,0x36,0x2d,0x39, 
+       0x64,0x0a,0x0f,0xd9, 0x21,0x68,0x5c,0xa6, 0xd1,0x9b,0x5b,0x54, 0x3a,0x24,0x36,0x2e, 
+       0xb1,0x0c,0x0a,0x67, 0x0f,0x93,0x57,0xe7, 0xd2,0xb4,0xee,0x96, 0x9e,0x1b,0x9b,0x91, 
+       0x4f,0x80,0xc0,0xc5, 0xa2,0x61,0xdc,0x20, 0x69,0x5a,0x77,0x4b, 0x16,0x1c,0x12,0x1a, 
+       0x0a,0xe2,0x93,0xba, 0xe5,0xc0,0xa0,0x2a, 0x43,0x3c,0x22,0xe0, 0x1d,0x12,0x1b,0x17, 
+       0x0b,0x0e,0x09,0x0d, 0xad,0xf2,0x8b,0xc7, 0xb9,0x2d,0xb6,0xa8, 0xc8,0x14,0x1e,0xa9, 
+       0x85,0x57,0xf1,0x19, 0x4c,0xaf,0x75,0x07, 0xbb,0xee,0x99,0xdd, 0xfd,0xa3,0x7f,0x60, 
+       0x9f,0xf7,0x01,0x26, 0xbc,0x5c,0x72,0xf5, 0xc5,0x44,0x66,0x3b, 0x34,0x5b,0xfb,0x7e, 
+       0x76,0x8b,0x43,0x29, 0xdc,0xcb,0x23,0xc6, 0x68,0xb6,0xed,0xfc, 0x63,0xb8,0xe4,0xf1, 
+       0xca,0xd7,0x31,0xdc, 0x10,0x42,0x63,0x85, 0x40,0x13,0x97,0x22, 0x20,0x84,0xc6,0x11, 
+       0x7d,0x85,0x4a,0x24, 0xf8,0xd2,0xbb,0x3d, 0x11,0xae,0xf9,0x32, 0x6d,0xc7,0x29,0xa1, 
+       0x4b,0x1d,0x9e,0x2f, 0xf3,0xdc,0xb2,0x30, 0xec,0x0d,0x86,0x52, 0xd0,0x77,0xc1,0xe3, 
+       0x6c,0x2b,0xb3,0x16, 0x99,0xa9,0x70,0xb9, 0xfa,0x11,0x94,0x48, 0x22,0x47,0xe9,0x64, 
+       0xc4,0xa8,0xfc,0x8c, 0x1a,0xa0,0xf0,0x3f, 0xd8,0x56,0x7d,0x2c, 0xef,0x22,0x33,0x90, 
+       0xc7,0x87,0x49,0x4e, 0xc1,0xd9,0x38,0xd1, 0xfe,0x8c,0xca,0xa2, 0x36,0x98,0xd4,0x0b, 
+       0xcf,0xa6,0xf5,0x81, 0x28,0xa5,0x7a,0xde, 0x26,0xda,0xb7,0x8e, 0xa4,0x3f,0xad,0xbf, 
+       0xe4,0x2c,0x3a,0x9d, 0x0d,0x50,0x78,0x92, 0x9b,0x6a,0x5f,0xcc, 0x62,0x54,0x7e,0x46, 
+       0xc2,0xf6,0x8d,0x13, 0xe8,0x90,0xd8,0xb8, 0x5e,0x2e,0x39,0xf7, 0xf5,0x82,0xc3,0xaf, 
+       0xbe,0x9f,0x5d,0x80, 0x7c,0x69,0xd0,0x93, 0xa9,0x6f,0xd5,0x2d, 0xb3,0xcf,0x25,0x12, 
+       0x3b,0xc8,0xac,0x99, 0xa7,0x10,0x18,0x7d, 0x6e,0xe8,0x9c,0x63, 0x7b,0xdb,0x3b,0xbb, 
+       0x09,0xcd,0x26,0x78, 0xf4,0x6e,0x59,0x18, 0x01,0xec,0x9a,0xb7, 0xa8,0x83,0x4f,0x9a, 
+       0x65,0xe6,0x95,0x6e, 0x7e,0xaa,0xff,0xe6, 0x08,0x21,0xbc,0xcf, 0xe6,0xef,0x15,0xe8, 
+       0xd9,0xba,0xe7,0x9b, 0xce,0x4a,0x6f,0x36, 0xd4,0xea,0x9f,0x09, 0xd6,0x29,0xb0,0x7c, 
+       0xaf,0x31,0xa4,0xb2, 0x31,0x2a,0x3f,0x23, 0x30,0xc6,0xa5,0x94, 0xc0,0x35,0xa2,0x66, 
+       0x37,0x74,0x4e,0xbc, 0xa6,0xfc,0x82,0xca, 0xb0,0xe0,0x90,0xd0, 0x15,0x33,0xa7,0xd8, 
+       0x4a,0xf1,0x04,0x98, 0xf7,0x41,0xec,0xda, 0x0e,0x7f,0xcd,0x50, 0x2f,0x17,0x91,0xf6, 
+       0x8d,0x76,0x4d,0xd6, 0x4d,0x43,0xef,0xb0, 0x54,0xcc,0xaa,0x4d, 0xdf,0xe4,0x96,0x04, 
+       0xe3,0x9e,0xd1,0xb5, 0x1b,0x4c,0x6a,0x88, 0xb8,0xc1,0x2c,0x1f, 0x7f,0x46,0x65,0x51, 
+       0x04,0x9d,0x5e,0xea, 0x5d,0x01,0x8c,0x35, 0x73,0xfa,0x87,0x74, 0x2e,0xfb,0x0b,0x41, 
+       0x5a,0xb3,0x67,0x1d, 0x52,0x92,0xdb,0xd2, 0x33,0xe9,0x10,0x56, 0x13,0x6d,0xd6,0x47, 
+       0x8c,0x9a,0xd7,0x61, 0x7a,0x37,0xa1,0x0c, 0x8e,0x59,0xf8,0x14, 0x89,0xeb,0x13,0x3c, 
+       0xee,0xce,0xa9,0x27, 0x35,0xb7,0x61,0xc9, 0xed,0xe1,0x1c,0xe5, 0x3c,0x7a,0x47,0xb1, 
+       0x59,0x9c,0xd2,0xdf, 0x3f,0x55,0xf2,0x73, 0x79,0x18,0x14,0xce, 0xbf,0x73,0xc7,0x37, 
+       0xea,0x53,0xf7,0xcd, 0x5b,0x5f,0xfd,0xaa, 0x14,0xdf,0x3d,0x6f, 0x86,0x78,0x44,0xdb, 
+       0x81,0xca,0xaf,0xf3, 0x3e,0xb9,0x68,0xc4, 0x2c,0x38,0x24,0x34, 0x5f,0xc2,0xa3,0x40, 
+       0x72,0x16,0x1d,0xc3, 0x0c,0xbc,0xe2,0x25, 0x8b,0x28,0x3c,0x49, 0x41,0xff,0x0d,0x95, 
+       0x71,0x39,0xa8,0x01, 0xde,0x08,0x0c,0xb3, 0x9c,0xd8,0xb4,0xe4, 0x90,0x64,0x56,0xc1, 
+       0x61,0x7b,0xcb,0x84, 0x70,0xd5,0x32,0xb6, 0x74,0x48,0x6c,0x5c, 0x42,0xd0,0xb8,0x57
+};
+
+static uint8_t T7[256][4]=
+{
+       0xa7,0x50,0x51,0xf4, 0x65,0x53,0x7e,0x41, 0xa4,0xc3,0x1a,0x17, 0x5e,0x96,0x3a,0x27, 
+       0x6b,0xcb,0x3b,0xab, 0x45,0xf1,0x1f,0x9d, 0x58,0xab,0xac,0xfa, 0x03,0x93,0x4b,0xe3, 
+       0xfa,0x55,0x20,0x30, 0x6d,0xf6,0xad,0x76, 0x76,0x91,0x88,0xcc, 0x4c,0x25,0xf5,0x02, 
+       0xd7,0xfc,0x4f,0xe5, 0xcb,0xd7,0xc5,0x2a, 0x44,0x80,0x26,0x35, 0xa3,0x8f,0xb5,0x62, 
+       0x5a,0x49,0xde,0xb1, 0x1b,0x67,0x25,0xba, 0x0e,0x98,0x45,0xea, 0xc0,0xe1,0x5d,0xfe, 
+       0x75,0x02,0xc3,0x2f, 0xf0,0x12,0x81,0x4c, 0x97,0xa3,0x8d,0x46, 0xf9,0xc6,0x6b,0xd3, 
+       0x5f,0xe7,0x03,0x8f, 0x9c,0x95,0x15,0x92, 0x7a,0xeb,0xbf,0x6d, 0x59,0xda,0x95,0x52, 
+       0x83,0x2d,0xd4,0xbe, 0x21,0xd3,0x58,0x74, 0x69,0x29,0x49,0xe0, 0xc8,0x44,0x8e,0xc9, 
+       0x89,0x6a,0x75,0xc2, 0x79,0x78,0xf4,0x8e, 0x3e,0x6b,0x99,0x58, 0x71,0xdd,0x27,0xb9, 
+       0x4f,0xb6,0xbe,0xe1, 0xad,0x17,0xf0,0x88, 0xac,0x66,0xc9,0x20, 0x3a,0xb4,0x7d,0xce, 
+       0x4a,0x18,0x63,0xdf, 0x31,0x82,0xe5,0x1a, 0x33,0x60,0x97,0x51, 0x7f,0x45,0x62,0x53, 
+       0x77,0xe0,0xb1,0x64, 0xae,0x84,0xbb,0x6b, 0xa0,0x1c,0xfe,0x81, 0x2b,0x94,0xf9,0x08, 
+       0x68,0x58,0x70,0x48, 0xfd,0x19,0x8f,0x45, 0x6c,0x87,0x94,0xde, 0xf8,0xb7,0x52,0x7b, 
+       0xd3,0x23,0xab,0x73, 0x02,0xe2,0x72,0x4b, 0x8f,0x57,0xe3,0x1f, 0xab,0x2a,0x66,0x55, 
+       0x28,0x07,0xb2,0xeb, 0xc2,0x03,0x2f,0xb5, 0x7b,0x9a,0x86,0xc5, 0x08,0xa5,0xd3,0x37, 
+       0x87,0xf2,0x30,0x28, 0xa5,0xb2,0x23,0xbf, 0x6a,0xba,0x02,0x03, 0x82,0x5c,0xed,0x16, 
+       0x1c,0x2b,0x8a,0xcf, 0xb4,0x92,0xa7,0x79, 0xf2,0xf0,0xf3,0x07, 0xe2,0xa1,0x4e,0x69, 
+       0xf4,0xcd,0x65,0xda, 0xbe,0xd5,0x06,0x05, 0x62,0x1f,0xd1,0x34, 0xfe,0x8a,0xc4,0xa6, 
+       0x53,0x9d,0x34,0x2e, 0x55,0xa0,0xa2,0xf3, 0xe1,0x32,0x05,0x8a, 0xeb,0x75,0xa4,0xf6, 
+       0xec,0x39,0x0b,0x83, 0xef,0xaa,0x40,0x60, 0x9f,0x06,0x5e,0x71, 0x10,0x51,0xbd,0x6e, 
+       0x8a,0xf9,0x3e,0x21, 0x06,0x3d,0x96,0xdd, 0x05,0xae,0xdd,0x3e, 0xbd,0x46,0x4d,0xe6, 
+       0x8d,0xb5,0x91,0x54, 0x5d,0x05,0x71,0xc4, 0xd4,0x6f,0x04,0x06, 0x15,0xff,0x60,0x50, 
+       0xfb,0x24,0x19,0x98, 0xe9,0x97,0xd6,0xbd, 0x43,0xcc,0x89,0x40, 0x9e,0x77,0x67,0xd9, 
+       0x42,0xbd,0xb0,0xe8, 0x8b,0x88,0x07,0x89, 0x5b,0x38,0xe7,0x19, 0xee,0xdb,0x79,0xc8, 
+       0x0a,0x47,0xa1,0x7c, 0x0f,0xe9,0x7c,0x42, 0x1e,0xc9,0xf8,0x84, 0x00,0x00,0x00,0x00, 
+       0x86,0x83,0x09,0x80, 0xed,0x48,0x32,0x2b, 0x70,0xac,0x1e,0x11, 0x72,0x4e,0x6c,0x5a, 
+       0xff,0xfb,0xfd,0x0e, 0x38,0x56,0x0f,0x85, 0xd5,0x1e,0x3d,0xae, 0x39,0x27,0x36,0x2d, 
+       0xd9,0x64,0x0a,0x0f, 0xa6,0x21,0x68,0x5c, 0x54,0xd1,0x9b,0x5b, 0x2e,0x3a,0x24,0x36, 
+       0x67,0xb1,0x0c,0x0a, 0xe7,0x0f,0x93,0x57, 0x96,0xd2,0xb4,0xee, 0x91,0x9e,0x1b,0x9b, 
+       0xc5,0x4f,0x80,0xc0, 0x20,0xa2,0x61,0xdc, 0x4b,0x69,0x5a,0x77, 0x1a,0x16,0x1c,0x12, 
+       0xba,0x0a,0xe2,0x93, 0x2a,0xe5,0xc0,0xa0, 0xe0,0x43,0x3c,0x22, 0x17,0x1d,0x12,0x1b, 
+       0x0d,0x0b,0x0e,0x09, 0xc7,0xad,0xf2,0x8b, 0xa8,0xb9,0x2d,0xb6, 0xa9,0xc8,0x14,0x1e, 
+       0x19,0x85,0x57,0xf1, 0x07,0x4c,0xaf,0x75, 0xdd,0xbb,0xee,0x99, 0x60,0xfd,0xa3,0x7f, 
+       0x26,0x9f,0xf7,0x01, 0xf5,0xbc,0x5c,0x72, 0x3b,0xc5,0x44,0x66, 0x7e,0x34,0x5b,0xfb, 
+       0x29,0x76,0x8b,0x43, 0xc6,0xdc,0xcb,0x23, 0xfc,0x68,0xb6,0xed, 0xf1,0x63,0xb8,0xe4, 
+       0xdc,0xca,0xd7,0x31, 0x85,0x10,0x42,0x63, 0x22,0x40,0x13,0x97, 0x11,0x20,0x84,0xc6, 
+       0x24,0x7d,0x85,0x4a, 0x3d,0xf8,0xd2,0xbb, 0x32,0x11,0xae,0xf9, 0xa1,0x6d,0xc7,0x29, 
+       0x2f,0x4b,0x1d,0x9e, 0x30,0xf3,0xdc,0xb2, 0x52,0xec,0x0d,0x86, 0xe3,0xd0,0x77,0xc1, 
+       0x16,0x6c,0x2b,0xb3, 0xb9,0x99,0xa9,0x70, 0x48,0xfa,0x11,0x94, 0x64,0x22,0x47,0xe9, 
+       0x8c,0xc4,0xa8,0xfc, 0x3f,0x1a,0xa0,0xf0, 0x2c,0xd8,0x56,0x7d, 0x90,0xef,0x22,0x33, 
+       0x4e,0xc7,0x87,0x49, 0xd1,0xc1,0xd9,0x38, 0xa2,0xfe,0x8c,0xca, 0x0b,0x36,0x98,0xd4, 
+       0x81,0xcf,0xa6,0xf5, 0xde,0x28,0xa5,0x7a, 0x8e,0x26,0xda,0xb7, 0xbf,0xa4,0x3f,0xad, 
+       0x9d,0xe4,0x2c,0x3a, 0x92,0x0d,0x50,0x78, 0xcc,0x9b,0x6a,0x5f, 0x46,0x62,0x54,0x7e, 
+       0x13,0xc2,0xf6,0x8d, 0xb8,0xe8,0x90,0xd8, 0xf7,0x5e,0x2e,0x39, 0xaf,0xf5,0x82,0xc3, 
+       0x80,0xbe,0x9f,0x5d, 0x93,0x7c,0x69,0xd0, 0x2d,0xa9,0x6f,0xd5, 0x12,0xb3,0xcf,0x25, 
+       0x99,0x3b,0xc8,0xac, 0x7d,0xa7,0x10,0x18, 0x63,0x6e,0xe8,0x9c, 0xbb,0x7b,0xdb,0x3b, 
+       0x78,0x09,0xcd,0x26, 0x18,0xf4,0x6e,0x59, 0xb7,0x01,0xec,0x9a, 0x9a,0xa8,0x83,0x4f, 
+       0x6e,0x65,0xe6,0x95, 0xe6,0x7e,0xaa,0xff, 0xcf,0x08,0x21,0xbc, 0xe8,0xe6,0xef,0x15, 
+       0x9b,0xd9,0xba,0xe7, 0x36,0xce,0x4a,0x6f, 0x09,0xd4,0xea,0x9f, 0x7c,0xd6,0x29,0xb0, 
+       0xb2,0xaf,0x31,0xa4, 0x23,0x31,0x2a,0x3f, 0x94,0x30,0xc6,0xa5, 0x66,0xc0,0x35,0xa2, 
+       0xbc,0x37,0x74,0x4e, 0xca,0xa6,0xfc,0x82, 0xd0,0xb0,0xe0,0x90, 0xd8,0x15,0x33,0xa7, 
+       0x98,0x4a,0xf1,0x04, 0xda,0xf7,0x41,0xec, 0x50,0x0e,0x7f,0xcd, 0xf6,0x2f,0x17,0x91, 
+       0xd6,0x8d,0x76,0x4d, 0xb0,0x4d,0x43,0xef, 0x4d,0x54,0xcc,0xaa, 0x04,0xdf,0xe4,0x96, 
+       0xb5,0xe3,0x9e,0xd1, 0x88,0x1b,0x4c,0x6a, 0x1f,0xb8,0xc1,0x2c, 0x51,0x7f,0x46,0x65, 
+       0xea,0x04,0x9d,0x5e, 0x35,0x5d,0x01,0x8c, 0x74,0x73,0xfa,0x87, 0x41,0x2e,0xfb,0x0b, 
+       0x1d,0x5a,0xb3,0x67, 0xd2,0x52,0x92,0xdb, 0x56,0x33,0xe9,0x10, 0x47,0x13,0x6d,0xd6, 
+       0x61,0x8c,0x9a,0xd7, 0x0c,0x7a,0x37,0xa1, 0x14,0x8e,0x59,0xf8, 0x3c,0x89,0xeb,0x13, 
+       0x27,0xee,0xce,0xa9, 0xc9,0x35,0xb7,0x61, 0xe5,0xed,0xe1,0x1c, 0xb1,0x3c,0x7a,0x47, 
+       0xdf,0x59,0x9c,0xd2, 0x73,0x3f,0x55,0xf2, 0xce,0x79,0x18,0x14, 0x37,0xbf,0x73,0xc7, 
+       0xcd,0xea,0x53,0xf7, 0xaa,0x5b,0x5f,0xfd, 0x6f,0x14,0xdf,0x3d, 0xdb,0x86,0x78,0x44, 
+       0xf3,0x81,0xca,0xaf, 0xc4,0x3e,0xb9,0x68, 0x34,0x2c,0x38,0x24, 0x40,0x5f,0xc2,0xa3, 
+       0xc3,0x72,0x16,0x1d, 0x25,0x0c,0xbc,0xe2, 0x49,0x8b,0x28,0x3c, 0x95,0x41,0xff,0x0d, 
+       0x01,0x71,0x39,0xa8, 0xb3,0xde,0x08,0x0c, 0xe4,0x9c,0xd8,0xb4, 0xc1,0x90,0x64,0x56, 
+       0x84,0x61,0x7b,0xcb, 0xb6,0x70,0xd5,0x32, 0x5c,0x74,0x48,0x6c, 0x57,0x42,0xd0,0xb8
+};
+
+static uint8_t T8[256][4]=
+{
+       0xf4,0xa7,0x50,0x51, 0x41,0x65,0x53,0x7e, 0x17,0xa4,0xc3,0x1a, 0x27,0x5e,0x96,0x3a, 
+       0xab,0x6b,0xcb,0x3b, 0x9d,0x45,0xf1,0x1f, 0xfa,0x58,0xab,0xac, 0xe3,0x03,0x93,0x4b, 
+       0x30,0xfa,0x55,0x20, 0x76,0x6d,0xf6,0xad, 0xcc,0x76,0x91,0x88, 0x02,0x4c,0x25,0xf5, 
+       0xe5,0xd7,0xfc,0x4f, 0x2a,0xcb,0xd7,0xc5, 0x35,0x44,0x80,0x26, 0x62,0xa3,0x8f,0xb5, 
+       0xb1,0x5a,0x49,0xde, 0xba,0x1b,0x67,0x25, 0xea,0x0e,0x98,0x45, 0xfe,0xc0,0xe1,0x5d, 
+       0x2f,0x75,0x02,0xc3, 0x4c,0xf0,0x12,0x81, 0x46,0x97,0xa3,0x8d, 0xd3,0xf9,0xc6,0x6b, 
+       0x8f,0x5f,0xe7,0x03, 0x92,0x9c,0x95,0x15, 0x6d,0x7a,0xeb,0xbf, 0x52,0x59,0xda,0x95, 
+       0xbe,0x83,0x2d,0xd4, 0x74,0x21,0xd3,0x58, 0xe0,0x69,0x29,0x49, 0xc9,0xc8,0x44,0x8e, 
+       0xc2,0x89,0x6a,0x75, 0x8e,0x79,0x78,0xf4, 0x58,0x3e,0x6b,0x99, 0xb9,0x71,0xdd,0x27, 
+       0xe1,0x4f,0xb6,0xbe, 0x88,0xad,0x17,0xf0, 0x20,0xac,0x66,0xc9, 0xce,0x3a,0xb4,0x7d, 
+       0xdf,0x4a,0x18,0x63, 0x1a,0x31,0x82,0xe5, 0x51,0x33,0x60,0x97, 0x53,0x7f,0x45,0x62, 
+       0x64,0x77,0xe0,0xb1, 0x6b,0xae,0x84,0xbb, 0x81,0xa0,0x1c,0xfe, 0x08,0x2b,0x94,0xf9, 
+       0x48,0x68,0x58,0x70, 0x45,0xfd,0x19,0x8f, 0xde,0x6c,0x87,0x94, 0x7b,0xf8,0xb7,0x52, 
+       0x73,0xd3,0x23,0xab, 0x4b,0x02,0xe2,0x72, 0x1f,0x8f,0x57,0xe3, 0x55,0xab,0x2a,0x66, 
+       0xeb,0x28,0x07,0xb2, 0xb5,0xc2,0x03,0x2f, 0xc5,0x7b,0x9a,0x86, 0x37,0x08,0xa5,0xd3, 
+       0x28,0x87,0xf2,0x30, 0xbf,0xa5,0xb2,0x23, 0x03,0x6a,0xba,0x02, 0x16,0x82,0x5c,0xed, 
+       0xcf,0x1c,0x2b,0x8a, 0x79,0xb4,0x92,0xa7, 0x07,0xf2,0xf0,0xf3, 0x69,0xe2,0xa1,0x4e, 
+       0xda,0xf4,0xcd,0x65, 0x05,0xbe,0xd5,0x06, 0x34,0x62,0x1f,0xd1, 0xa6,0xfe,0x8a,0xc4, 
+       0x2e,0x53,0x9d,0x34, 0xf3,0x55,0xa0,0xa2, 0x8a,0xe1,0x32,0x05, 0xf6,0xeb,0x75,0xa4, 
+       0x83,0xec,0x39,0x0b, 0x60,0xef,0xaa,0x40, 0x71,0x9f,0x06,0x5e, 0x6e,0x10,0x51,0xbd, 
+       0x21,0x8a,0xf9,0x3e, 0xdd,0x06,0x3d,0x96, 0x3e,0x05,0xae,0xdd, 0xe6,0xbd,0x46,0x4d, 
+       0x54,0x8d,0xb5,0x91, 0xc4,0x5d,0x05,0x71, 0x06,0xd4,0x6f,0x04, 0x50,0x15,0xff,0x60, 
+       0x98,0xfb,0x24,0x19, 0xbd,0xe9,0x97,0xd6, 0x40,0x43,0xcc,0x89, 0xd9,0x9e,0x77,0x67, 
+       0xe8,0x42,0xbd,0xb0, 0x89,0x8b,0x88,0x07, 0x19,0x5b,0x38,0xe7, 0xc8,0xee,0xdb,0x79, 
+       0x7c,0x0a,0x47,0xa1, 0x42,0x0f,0xe9,0x7c, 0x84,0x1e,0xc9,0xf8, 0x00,0x00,0x00,0x00, 
+       0x80,0x86,0x83,0x09, 0x2b,0xed,0x48,0x32, 0x11,0x70,0xac,0x1e, 0x5a,0x72,0x4e,0x6c, 
+       0x0e,0xff,0xfb,0xfd, 0x85,0x38,0x56,0x0f, 0xae,0xd5,0x1e,0x3d, 0x2d,0x39,0x27,0x36, 
+       0x0f,0xd9,0x64,0x0a, 0x5c,0xa6,0x21,0x68, 0x5b,0x54,0xd1,0x9b, 0x36,0x2e,0x3a,0x24, 
+       0x0a,0x67,0xb1,0x0c, 0x57,0xe7,0x0f,0x93, 0xee,0x96,0xd2,0xb4, 0x9b,0x91,0x9e,0x1b, 
+       0xc0,0xc5,0x4f,0x80, 0xdc,0x20,0xa2,0x61, 0x77,0x4b,0x69,0x5a, 0x12,0x1a,0x16,0x1c, 
+       0x93,0xba,0x0a,0xe2, 0xa0,0x2a,0xe5,0xc0, 0x22,0xe0,0x43,0x3c, 0x1b,0x17,0x1d,0x12, 
+       0x09,0x0d,0x0b,0x0e, 0x8b,0xc7,0xad,0xf2, 0xb6,0xa8,0xb9,0x2d, 0x1e,0xa9,0xc8,0x14, 
+       0xf1,0x19,0x85,0x57, 0x75,0x07,0x4c,0xaf, 0x99,0xdd,0xbb,0xee, 0x7f,0x60,0xfd,0xa3, 
+       0x01,0x26,0x9f,0xf7, 0x72,0xf5,0xbc,0x5c, 0x66,0x3b,0xc5,0x44, 0xfb,0x7e,0x34,0x5b, 
+       0x43,0x29,0x76,0x8b, 0x23,0xc6,0xdc,0xcb, 0xed,0xfc,0x68,0xb6, 0xe4,0xf1,0x63,0xb8, 
+       0x31,0xdc,0xca,0xd7, 0x63,0x85,0x10,0x42, 0x97,0x22,0x40,0x13, 0xc6,0x11,0x20,0x84, 
+       0x4a,0x24,0x7d,0x85, 0xbb,0x3d,0xf8,0xd2, 0xf9,0x32,0x11,0xae, 0x29,0xa1,0x6d,0xc7, 
+       0x9e,0x2f,0x4b,0x1d, 0xb2,0x30,0xf3,0xdc, 0x86,0x52,0xec,0x0d, 0xc1,0xe3,0xd0,0x77, 
+       0xb3,0x16,0x6c,0x2b, 0x70,0xb9,0x99,0xa9, 0x94,0x48,0xfa,0x11, 0xe9,0x64,0x22,0x47, 
+       0xfc,0x8c,0xc4,0xa8, 0xf0,0x3f,0x1a,0xa0, 0x7d,0x2c,0xd8,0x56, 0x33,0x90,0xef,0x22, 
+       0x49,0x4e,0xc7,0x87, 0x38,0xd1,0xc1,0xd9, 0xca,0xa2,0xfe,0x8c, 0xd4,0x0b,0x36,0x98, 
+       0xf5,0x81,0xcf,0xa6, 0x7a,0xde,0x28,0xa5, 0xb7,0x8e,0x26,0xda, 0xad,0xbf,0xa4,0x3f, 
+       0x3a,0x9d,0xe4,0x2c, 0x78,0x92,0x0d,0x50, 0x5f,0xcc,0x9b,0x6a, 0x7e,0x46,0x62,0x54, 
+       0x8d,0x13,0xc2,0xf6, 0xd8,0xb8,0xe8,0x90, 0x39,0xf7,0x5e,0x2e, 0xc3,0xaf,0xf5,0x82, 
+       0x5d,0x80,0xbe,0x9f, 0xd0,0x93,0x7c,0x69, 0xd5,0x2d,0xa9,0x6f, 0x25,0x12,0xb3,0xcf, 
+       0xac,0x99,0x3b,0xc8, 0x18,0x7d,0xa7,0x10, 0x9c,0x63,0x6e,0xe8, 0x3b,0xbb,0x7b,0xdb, 
+       0x26,0x78,0x09,0xcd, 0x59,0x18,0xf4,0x6e, 0x9a,0xb7,0x01,0xec, 0x4f,0x9a,0xa8,0x83, 
+       0x95,0x6e,0x65,0xe6, 0xff,0xe6,0x7e,0xaa, 0xbc,0xcf,0x08,0x21, 0x15,0xe8,0xe6,0xef, 
+       0xe7,0x9b,0xd9,0xba, 0x6f,0x36,0xce,0x4a, 0x9f,0x09,0xd4,0xea, 0xb0,0x7c,0xd6,0x29, 
+       0xa4,0xb2,0xaf,0x31, 0x3f,0x23,0x31,0x2a, 0xa5,0x94,0x30,0xc6, 0xa2,0x66,0xc0,0x35, 
+       0x4e,0xbc,0x37,0x74, 0x82,0xca,0xa6,0xfc, 0x90,0xd0,0xb0,0xe0, 0xa7,0xd8,0x15,0x33, 
+       0x04,0x98,0x4a,0xf1, 0xec,0xda,0xf7,0x41, 0xcd,0x50,0x0e,0x7f, 0x91,0xf6,0x2f,0x17, 
+       0x4d,0xd6,0x8d,0x76, 0xef,0xb0,0x4d,0x43, 0xaa,0x4d,0x54,0xcc, 0x96,0x04,0xdf,0xe4, 
+       0xd1,0xb5,0xe3,0x9e, 0x6a,0x88,0x1b,0x4c, 0x2c,0x1f,0xb8,0xc1, 0x65,0x51,0x7f,0x46, 
+       0x5e,0xea,0x04,0x9d, 0x8c,0x35,0x5d,0x01, 0x87,0x74,0x73,0xfa, 0x0b,0x41,0x2e,0xfb, 
+       0x67,0x1d,0x5a,0xb3, 0xdb,0xd2,0x52,0x92, 0x10,0x56,0x33,0xe9, 0xd6,0x47,0x13,0x6d, 
+       0xd7,0x61,0x8c,0x9a, 0xa1,0x0c,0x7a,0x37, 0xf8,0x14,0x8e,0x59, 0x13,0x3c,0x89,0xeb, 
+       0xa9,0x27,0xee,0xce, 0x61,0xc9,0x35,0xb7, 0x1c,0xe5,0xed,0xe1, 0x47,0xb1,0x3c,0x7a, 
+       0xd2,0xdf,0x59,0x9c, 0xf2,0x73,0x3f,0x55, 0x14,0xce,0x79,0x18, 0xc7,0x37,0xbf,0x73, 
+       0xf7,0xcd,0xea,0x53, 0xfd,0xaa,0x5b,0x5f, 0x3d,0x6f,0x14,0xdf, 0x44,0xdb,0x86,0x78, 
+       0xaf,0xf3,0x81,0xca, 0x68,0xc4,0x3e,0xb9, 0x24,0x34,0x2c,0x38, 0xa3,0x40,0x5f,0xc2, 
+       0x1d,0xc3,0x72,0x16, 0xe2,0x25,0x0c,0xbc, 0x3c,0x49,0x8b,0x28, 0x0d,0x95,0x41,0xff, 
+       0xa8,0x01,0x71,0x39, 0x0c,0xb3,0xde,0x08, 0xb4,0xe4,0x9c,0xd8, 0x56,0xc1,0x90,0x64, 
+       0xcb,0x84,0x61,0x7b, 0x32,0xb6,0x70,0xd5, 0x6c,0x5c,0x74,0x48, 0xb8,0x57,0x42,0xd0
+};
+
+static uint8_t S5[256]=
+{
+       0x52,0x09,0x6a,0xd5,
+       0x30,0x36,0xa5,0x38,
+       0xbf,0x40,0xa3,0x9e,
+       0x81,0xf3,0xd7,0xfb,
+       0x7c,0xe3,0x39,0x82,
+       0x9b,0x2f,0xff,0x87,
+       0x34,0x8e,0x43,0x44,
+       0xc4,0xde,0xe9,0xcb,
+       0x54,0x7b,0x94,0x32,
+       0xa6,0xc2,0x23,0x3d,
+       0xee,0x4c,0x95,0x0b,
+       0x42,0xfa,0xc3,0x4e,
+       0x08,0x2e,0xa1,0x66,
+       0x28,0xd9,0x24,0xb2,
+       0x76,0x5b,0xa2,0x49,
+       0x6d,0x8b,0xd1,0x25,
+       0x72,0xf8,0xf6,0x64,
+       0x86,0x68,0x98,0x16,
+       0xd4,0xa4,0x5c,0xcc,
+       0x5d,0x65,0xb6,0x92,
+       0x6c,0x70,0x48,0x50,
+       0xfd,0xed,0xb9,0xda,
+       0x5e,0x15,0x46,0x57,
+       0xa7,0x8d,0x9d,0x84,
+       0x90,0xd8,0xab,0x00,
+       0x8c,0xbc,0xd3,0x0a,
+       0xf7,0xe4,0x58,0x05,
+       0xb8,0xb3,0x45,0x06,
+       0xd0,0x2c,0x1e,0x8f,
+       0xca,0x3f,0x0f,0x02,
+       0xc1,0xaf,0xbd,0x03,
+       0x01,0x13,0x8a,0x6b,
+       0x3a,0x91,0x11,0x41,
+       0x4f,0x67,0xdc,0xea,
+       0x97,0xf2,0xcf,0xce,
+       0xf0,0xb4,0xe6,0x73,
+       0x96,0xac,0x74,0x22,
+       0xe7,0xad,0x35,0x85,
+       0xe2,0xf9,0x37,0xe8,
+       0x1c,0x75,0xdf,0x6e,
+       0x47,0xf1,0x1a,0x71,
+       0x1d,0x29,0xc5,0x89,
+       0x6f,0xb7,0x62,0x0e,
+       0xaa,0x18,0xbe,0x1b,
+       0xfc,0x56,0x3e,0x4b,
+       0xc6,0xd2,0x79,0x20,
+       0x9a,0xdb,0xc0,0xfe,
+       0x78,0xcd,0x5a,0xf4,
+       0x1f,0xdd,0xa8,0x33,
+       0x88,0x07,0xc7,0x31,
+       0xb1,0x12,0x10,0x59,
+       0x27,0x80,0xec,0x5f,
+       0x60,0x51,0x7f,0xa9,
+       0x19,0xb5,0x4a,0x0d,
+       0x2d,0xe5,0x7a,0x9f,
+       0x93,0xc9,0x9c,0xef,
+       0xa0,0xe0,0x3b,0x4d,
+       0xae,0x2a,0xf5,0xb0,
+       0xc8,0xeb,0xbb,0x3c,
+       0x83,0x53,0x99,0x61,
+       0x17,0x2b,0x04,0x7e,
+       0xba,0x77,0xd6,0x26,
+       0xe1,0x69,0x14,0x63,
+       0x55,0x21,0x0c,0x7d
+};
+
+static uint8_t U1[256][4]=
+{
+       0x00,0x00,0x00,0x00, 0x0e,0x09,0x0d,0x0b, 0x1c,0x12,0x1a,0x16, 0x12,0x1b,0x17,0x1d, 
+       0x38,0x24,0x34,0x2c, 0x36,0x2d,0x39,0x27, 0x24,0x36,0x2e,0x3a, 0x2a,0x3f,0x23,0x31, 
+       0x70,0x48,0x68,0x58, 0x7e,0x41,0x65,0x53, 0x6c,0x5a,0x72,0x4e, 0x62,0x53,0x7f,0x45, 
+       0x48,0x6c,0x5c,0x74, 0x46,0x65,0x51,0x7f, 0x54,0x7e,0x46,0x62, 0x5a,0x77,0x4b,0x69, 
+       0xe0,0x90,0xd0,0xb0, 0xee,0x99,0xdd,0xbb, 0xfc,0x82,0xca,0xa6, 0xf2,0x8b,0xc7,0xad, 
+       0xd8,0xb4,0xe4,0x9c, 0xd6,0xbd,0xe9,0x97, 0xc4,0xa6,0xfe,0x8a, 0xca,0xaf,0xf3,0x81, 
+       0x90,0xd8,0xb8,0xe8, 0x9e,0xd1,0xb5,0xe3, 0x8c,0xca,0xa2,0xfe, 0x82,0xc3,0xaf,0xf5, 
+       0xa8,0xfc,0x8c,0xc4, 0xa6,0xf5,0x81,0xcf, 0xb4,0xee,0x96,0xd2, 0xba,0xe7,0x9b,0xd9, 
+       0xdb,0x3b,0xbb,0x7b, 0xd5,0x32,0xb6,0x70, 0xc7,0x29,0xa1,0x6d, 0xc9,0x20,0xac,0x66, 
+       0xe3,0x1f,0x8f,0x57, 0xed,0x16,0x82,0x5c, 0xff,0x0d,0x95,0x41, 0xf1,0x04,0x98,0x4a, 
+       0xab,0x73,0xd3,0x23, 0xa5,0x7a,0xde,0x28, 0xb7,0x61,0xc9,0x35, 0xb9,0x68,0xc4,0x3e, 
+       0x93,0x57,0xe7,0x0f, 0x9d,0x5e,0xea,0x04, 0x8f,0x45,0xfd,0x19, 0x81,0x4c,0xf0,0x12, 
+       0x3b,0xab,0x6b,0xcb, 0x35,0xa2,0x66,0xc0, 0x27,0xb9,0x71,0xdd, 0x29,0xb0,0x7c,0xd6, 
+       0x03,0x8f,0x5f,0xe7, 0x0d,0x86,0x52,0xec, 0x1f,0x9d,0x45,0xf1, 0x11,0x94,0x48,0xfa, 
+       0x4b,0xe3,0x03,0x93, 0x45,0xea,0x0e,0x98, 0x57,0xf1,0x19,0x85, 0x59,0xf8,0x14,0x8e, 
+       0x73,0xc7,0x37,0xbf, 0x7d,0xce,0x3a,0xb4, 0x6f,0xd5,0x2d,0xa9, 0x61,0xdc,0x20,0xa2, 
+       0xad,0x76,0x6d,0xf6, 0xa3,0x7f,0x60,0xfd, 0xb1,0x64,0x77,0xe0, 0xbf,0x6d,0x7a,0xeb, 
+       0x95,0x52,0x59,0xda, 0x9b,0x5b,0x54,0xd1, 0x89,0x40,0x43,0xcc, 0x87,0x49,0x4e,0xc7, 
+       0xdd,0x3e,0x05,0xae, 0xd3,0x37,0x08,0xa5, 0xc1,0x2c,0x1f,0xb8, 0xcf,0x25,0x12,0xb3, 
+       0xe5,0x1a,0x31,0x82, 0xeb,0x13,0x3c,0x89, 0xf9,0x08,0x2b,0x94, 0xf7,0x01,0x26,0x9f, 
+       0x4d,0xe6,0xbd,0x46, 0x43,0xef,0xb0,0x4d, 0x51,0xf4,0xa7,0x50, 0x5f,0xfd,0xaa,0x5b, 
+       0x75,0xc2,0x89,0x6a, 0x7b,0xcb,0x84,0x61, 0x69,0xd0,0x93,0x7c, 0x67,0xd9,0x9e,0x77, 
+       0x3d,0xae,0xd5,0x1e, 0x33,0xa7,0xd8,0x15, 0x21,0xbc,0xcf,0x08, 0x2f,0xb5,0xc2,0x03, 
+       0x05,0x8a,0xe1,0x32, 0x0b,0x83,0xec,0x39, 0x19,0x98,0xfb,0x24, 0x17,0x91,0xf6,0x2f, 
+       0x76,0x4d,0xd6,0x8d, 0x78,0x44,0xdb,0x86, 0x6a,0x5f,0xcc,0x9b, 0x64,0x56,0xc1,0x90, 
+       0x4e,0x69,0xe2,0xa1, 0x40,0x60,0xef,0xaa, 0x52,0x7b,0xf8,0xb7, 0x5c,0x72,0xf5,0xbc, 
+       0x06,0x05,0xbe,0xd5, 0x08,0x0c,0xb3,0xde, 0x1a,0x17,0xa4,0xc3, 0x14,0x1e,0xa9,0xc8, 
+       0x3e,0x21,0x8a,0xf9, 0x30,0x28,0x87,0xf2, 0x22,0x33,0x90,0xef, 0x2c,0x3a,0x9d,0xe4, 
+       0x96,0xdd,0x06,0x3d, 0x98,0xd4,0x0b,0x36, 0x8a,0xcf,0x1c,0x2b, 0x84,0xc6,0x11,0x20, 
+       0xae,0xf9,0x32,0x11, 0xa0,0xf0,0x3f,0x1a, 0xb2,0xeb,0x28,0x07, 0xbc,0xe2,0x25,0x0c, 
+       0xe6,0x95,0x6e,0x65, 0xe8,0x9c,0x63,0x6e, 0xfa,0x87,0x74,0x73, 0xf4,0x8e,0x79,0x78, 
+       0xde,0xb1,0x5a,0x49, 0xd0,0xb8,0x57,0x42, 0xc2,0xa3,0x40,0x5f, 0xcc,0xaa,0x4d,0x54, 
+       0x41,0xec,0xda,0xf7, 0x4f,0xe5,0xd7,0xfc, 0x5d,0xfe,0xc0,0xe1, 0x53,0xf7,0xcd,0xea, 
+       0x79,0xc8,0xee,0xdb, 0x77,0xc1,0xe3,0xd0, 0x65,0xda,0xf4,0xcd, 0x6b,0xd3,0xf9,0xc6, 
+       0x31,0xa4,0xb2,0xaf, 0x3f,0xad,0xbf,0xa4, 0x2d,0xb6,0xa8,0xb9, 0x23,0xbf,0xa5,0xb2, 
+       0x09,0x80,0x86,0x83, 0x07,0x89,0x8b,0x88, 0x15,0x92,0x9c,0x95, 0x1b,0x9b,0x91,0x9e, 
+       0xa1,0x7c,0x0a,0x47, 0xaf,0x75,0x07,0x4c, 0xbd,0x6e,0x10,0x51, 0xb3,0x67,0x1d,0x5a, 
+       0x99,0x58,0x3e,0x6b, 0x97,0x51,0x33,0x60, 0x85,0x4a,0x24,0x7d, 0x8b,0x43,0x29,0x76, 
+       0xd1,0x34,0x62,0x1f, 0xdf,0x3d,0x6f,0x14, 0xcd,0x26,0x78,0x09, 0xc3,0x2f,0x75,0x02, 
+       0xe9,0x10,0x56,0x33, 0xe7,0x19,0x5b,0x38, 0xf5,0x02,0x4c,0x25, 0xfb,0x0b,0x41,0x2e, 
+       0x9a,0xd7,0x61,0x8c, 0x94,0xde,0x6c,0x87, 0x86,0xc5,0x7b,0x9a, 0x88,0xcc,0x76,0x91, 
+       0xa2,0xf3,0x55,0xa0, 0xac,0xfa,0x58,0xab, 0xbe,0xe1,0x4f,0xb6, 0xb0,0xe8,0x42,0xbd, 
+       0xea,0x9f,0x09,0xd4, 0xe4,0x96,0x04,0xdf, 0xf6,0x8d,0x13,0xc2, 0xf8,0x84,0x1e,0xc9, 
+       0xd2,0xbb,0x3d,0xf8, 0xdc,0xb2,0x30,0xf3, 0xce,0xa9,0x27,0xee, 0xc0,0xa0,0x2a,0xe5, 
+       0x7a,0x47,0xb1,0x3c, 0x74,0x4e,0xbc,0x37, 0x66,0x55,0xab,0x2a, 0x68,0x5c,0xa6,0x21, 
+       0x42,0x63,0x85,0x10, 0x4c,0x6a,0x88,0x1b, 0x5e,0x71,0x9f,0x06, 0x50,0x78,0x92,0x0d, 
+       0x0a,0x0f,0xd9,0x64, 0x04,0x06,0xd4,0x6f, 0x16,0x1d,0xc3,0x72, 0x18,0x14,0xce,0x79, 
+       0x32,0x2b,0xed,0x48, 0x3c,0x22,0xe0,0x43, 0x2e,0x39,0xf7,0x5e, 0x20,0x30,0xfa,0x55, 
+       0xec,0x9a,0xb7,0x01, 0xe2,0x93,0xba,0x0a, 0xf0,0x88,0xad,0x17, 0xfe,0x81,0xa0,0x1c, 
+       0xd4,0xbe,0x83,0x2d, 0xda,0xb7,0x8e,0x26, 0xc8,0xac,0x99,0x3b, 0xc6,0xa5,0x94,0x30, 
+       0x9c,0xd2,0xdf,0x59, 0x92,0xdb,0xd2,0x52, 0x80,0xc0,0xc5,0x4f, 0x8e,0xc9,0xc8,0x44, 
+       0xa4,0xf6,0xeb,0x75, 0xaa,0xff,0xe6,0x7e, 0xb8,0xe4,0xf1,0x63, 0xb6,0xed,0xfc,0x68, 
+       0x0c,0x0a,0x67,0xb1, 0x02,0x03,0x6a,0xba, 0x10,0x18,0x7d,0xa7, 0x1e,0x11,0x70,0xac, 
+       0x34,0x2e,0x53,0x9d, 0x3a,0x27,0x5e,0x96, 0x28,0x3c,0x49,0x8b, 0x26,0x35,0x44,0x80, 
+       0x7c,0x42,0x0f,0xe9, 0x72,0x4b,0x02,0xe2, 0x60,0x50,0x15,0xff, 0x6e,0x59,0x18,0xf4, 
+       0x44,0x66,0x3b,0xc5, 0x4a,0x6f,0x36,0xce, 0x58,0x74,0x21,0xd3, 0x56,0x7d,0x2c,0xd8, 
+       0x37,0xa1,0x0c,0x7a, 0x39,0xa8,0x01,0x71, 0x2b,0xb3,0x16,0x6c, 0x25,0xba,0x1b,0x67, 
+       0x0f,0x85,0x38,0x56, 0x01,0x8c,0x35,0x5d, 0x13,0x97,0x22,0x40, 0x1d,0x9e,0x2f,0x4b, 
+       0x47,0xe9,0x64,0x22, 0x49,0xe0,0x69,0x29, 0x5b,0xfb,0x7e,0x34, 0x55,0xf2,0x73,0x3f, 
+       0x7f,0xcd,0x50,0x0e, 0x71,0xc4,0x5d,0x05, 0x63,0xdf,0x4a,0x18, 0x6d,0xd6,0x47,0x13, 
+       0xd7,0x31,0xdc,0xca, 0xd9,0x38,0xd1,0xc1, 0xcb,0x23,0xc6,0xdc, 0xc5,0x2a,0xcb,0xd7, 
+       0xef,0x15,0xe8,0xe6, 0xe1,0x1c,0xe5,0xed, 0xf3,0x07,0xf2,0xf0, 0xfd,0x0e,0xff,0xfb, 
+       0xa7,0x79,0xb4,0x92, 0xa9,0x70,0xb9,0x99, 0xbb,0x6b,0xae,0x84, 0xb5,0x62,0xa3,0x8f, 
+       0x9f,0x5d,0x80,0xbe, 0x91,0x54,0x8d,0xb5, 0x83,0x4f,0x9a,0xa8, 0x8d,0x46,0x97,0xa3
+};
+       
+static uint8_t U2[256][4]=
+{
+       0x00,0x00,0x00,0x00, 0x0b,0x0e,0x09,0x0d, 0x16,0x1c,0x12,0x1a, 0x1d,0x12,0x1b,0x17, 
+       0x2c,0x38,0x24,0x34, 0x27,0x36,0x2d,0x39, 0x3a,0x24,0x36,0x2e, 0x31,0x2a,0x3f,0x23, 
+       0x58,0x70,0x48,0x68, 0x53,0x7e,0x41,0x65, 0x4e,0x6c,0x5a,0x72, 0x45,0x62,0x53,0x7f, 
+       0x74,0x48,0x6c,0x5c, 0x7f,0x46,0x65,0x51, 0x62,0x54,0x7e,0x46, 0x69,0x5a,0x77,0x4b, 
+       0xb0,0xe0,0x90,0xd0, 0xbb,0xee,0x99,0xdd, 0xa6,0xfc,0x82,0xca, 0xad,0xf2,0x8b,0xc7, 
+       0x9c,0xd8,0xb4,0xe4, 0x97,0xd6,0xbd,0xe9, 0x8a,0xc4,0xa6,0xfe, 0x81,0xca,0xaf,0xf3, 
+       0xe8,0x90,0xd8,0xb8, 0xe3,0x9e,0xd1,0xb5, 0xfe,0x8c,0xca,0xa2, 0xf5,0x82,0xc3,0xaf, 
+       0xc4,0xa8,0xfc,0x8c, 0xcf,0xa6,0xf5,0x81, 0xd2,0xb4,0xee,0x96, 0xd9,0xba,0xe7,0x9b, 
+       0x7b,0xdb,0x3b,0xbb, 0x70,0xd5,0x32,0xb6, 0x6d,0xc7,0x29,0xa1, 0x66,0xc9,0x20,0xac, 
+       0x57,0xe3,0x1f,0x8f, 0x5c,0xed,0x16,0x82, 0x41,0xff,0x0d,0x95, 0x4a,0xf1,0x04,0x98, 
+       0x23,0xab,0x73,0xd3, 0x28,0xa5,0x7a,0xde, 0x35,0xb7,0x61,0xc9, 0x3e,0xb9,0x68,0xc4, 
+       0x0f,0x93,0x57,0xe7, 0x04,0x9d,0x5e,0xea, 0x19,0x8f,0x45,0xfd, 0x12,0x81,0x4c,0xf0, 
+       0xcb,0x3b,0xab,0x6b, 0xc0,0x35,0xa2,0x66, 0xdd,0x27,0xb9,0x71, 0xd6,0x29,0xb0,0x7c, 
+       0xe7,0x03,0x8f,0x5f, 0xec,0x0d,0x86,0x52, 0xf1,0x1f,0x9d,0x45, 0xfa,0x11,0x94,0x48, 
+       0x93,0x4b,0xe3,0x03, 0x98,0x45,0xea,0x0e, 0x85,0x57,0xf1,0x19, 0x8e,0x59,0xf8,0x14, 
+       0xbf,0x73,0xc7,0x37, 0xb4,0x7d,0xce,0x3a, 0xa9,0x6f,0xd5,0x2d, 0xa2,0x61,0xdc,0x20, 
+       0xf6,0xad,0x76,0x6d, 0xfd,0xa3,0x7f,0x60, 0xe0,0xb1,0x64,0x77, 0xeb,0xbf,0x6d,0x7a, 
+       0xda,0x95,0x52,0x59, 0xd1,0x9b,0x5b,0x54, 0xcc,0x89,0x40,0x43, 0xc7,0x87,0x49,0x4e, 
+       0xae,0xdd,0x3e,0x05, 0xa5,0xd3,0x37,0x08, 0xb8,0xc1,0x2c,0x1f, 0xb3,0xcf,0x25,0x12, 
+       0x82,0xe5,0x1a,0x31, 0x89,0xeb,0x13,0x3c, 0x94,0xf9,0x08,0x2b, 0x9f,0xf7,0x01,0x26, 
+       0x46,0x4d,0xe6,0xbd, 0x4d,0x43,0xef,0xb0, 0x50,0x51,0xf4,0xa7, 0x5b,0x5f,0xfd,0xaa, 
+       0x6a,0x75,0xc2,0x89, 0x61,0x7b,0xcb,0x84, 0x7c,0x69,0xd0,0x93, 0x77,0x67,0xd9,0x9e, 
+       0x1e,0x3d,0xae,0xd5, 0x15,0x33,0xa7,0xd8, 0x08,0x21,0xbc,0xcf, 0x03,0x2f,0xb5,0xc2, 
+       0x32,0x05,0x8a,0xe1, 0x39,0x0b,0x83,0xec, 0x24,0x19,0x98,0xfb, 0x2f,0x17,0x91,0xf6, 
+       0x8d,0x76,0x4d,0xd6, 0x86,0x78,0x44,0xdb, 0x9b,0x6a,0x5f,0xcc, 0x90,0x64,0x56,0xc1, 
+       0xa1,0x4e,0x69,0xe2, 0xaa,0x40,0x60,0xef, 0xb7,0x52,0x7b,0xf8, 0xbc,0x5c,0x72,0xf5, 
+       0xd5,0x06,0x05,0xbe, 0xde,0x08,0x0c,0xb3, 0xc3,0x1a,0x17,0xa4, 0xc8,0x14,0x1e,0xa9, 
+       0xf9,0x3e,0x21,0x8a, 0xf2,0x30,0x28,0x87, 0xef,0x22,0x33,0x90, 0xe4,0x2c,0x3a,0x9d, 
+       0x3d,0x96,0xdd,0x06, 0x36,0x98,0xd4,0x0b, 0x2b,0x8a,0xcf,0x1c, 0x20,0x84,0xc6,0x11, 
+       0x11,0xae,0xf9,0x32, 0x1a,0xa0,0xf0,0x3f, 0x07,0xb2,0xeb,0x28, 0x0c,0xbc,0xe2,0x25, 
+       0x65,0xe6,0x95,0x6e, 0x6e,0xe8,0x9c,0x63, 0x73,0xfa,0x87,0x74, 0x78,0xf4,0x8e,0x79, 
+       0x49,0xde,0xb1,0x5a, 0x42,0xd0,0xb8,0x57, 0x5f,0xc2,0xa3,0x40, 0x54,0xcc,0xaa,0x4d, 
+       0xf7,0x41,0xec,0xda, 0xfc,0x4f,0xe5,0xd7, 0xe1,0x5d,0xfe,0xc0, 0xea,0x53,0xf7,0xcd, 
+       0xdb,0x79,0xc8,0xee, 0xd0,0x77,0xc1,0xe3, 0xcd,0x65,0xda,0xf4, 0xc6,0x6b,0xd3,0xf9, 
+       0xaf,0x31,0xa4,0xb2, 0xa4,0x3f,0xad,0xbf, 0xb9,0x2d,0xb6,0xa8, 0xb2,0x23,0xbf,0xa5, 
+       0x83,0x09,0x80,0x86, 0x88,0x07,0x89,0x8b, 0x95,0x15,0x92,0x9c, 0x9e,0x1b,0x9b,0x91, 
+       0x47,0xa1,0x7c,0x0a, 0x4c,0xaf,0x75,0x07, 0x51,0xbd,0x6e,0x10, 0x5a,0xb3,0x67,0x1d, 
+       0x6b,0x99,0x58,0x3e, 0x60,0x97,0x51,0x33, 0x7d,0x85,0x4a,0x24, 0x76,0x8b,0x43,0x29, 
+       0x1f,0xd1,0x34,0x62, 0x14,0xdf,0x3d,0x6f, 0x09,0xcd,0x26,0x78, 0x02,0xc3,0x2f,0x75, 
+       0x33,0xe9,0x10,0x56, 0x38,0xe7,0x19,0x5b, 0x25,0xf5,0x02,0x4c, 0x2e,0xfb,0x0b,0x41, 
+       0x8c,0x9a,0xd7,0x61, 0x87,0x94,0xde,0x6c, 0x9a,0x86,0xc5,0x7b, 0x91,0x88,0xcc,0x76, 
+       0xa0,0xa2,0xf3,0x55, 0xab,0xac,0xfa,0x58, 0xb6,0xbe,0xe1,0x4f, 0xbd,0xb0,0xe8,0x42, 
+       0xd4,0xea,0x9f,0x09, 0xdf,0xe4,0x96,0x04, 0xc2,0xf6,0x8d,0x13, 0xc9,0xf8,0x84,0x1e, 
+       0xf8,0xd2,0xbb,0x3d, 0xf3,0xdc,0xb2,0x30, 0xee,0xce,0xa9,0x27, 0xe5,0xc0,0xa0,0x2a, 
+       0x3c,0x7a,0x47,0xb1, 0x37,0x74,0x4e,0xbc, 0x2a,0x66,0x55,0xab, 0x21,0x68,0x5c,0xa6, 
+       0x10,0x42,0x63,0x85, 0x1b,0x4c,0x6a,0x88, 0x06,0x5e,0x71,0x9f, 0x0d,0x50,0x78,0x92, 
+       0x64,0x0a,0x0f,0xd9, 0x6f,0x04,0x06,0xd4, 0x72,0x16,0x1d,0xc3, 0x79,0x18,0x14,0xce, 
+       0x48,0x32,0x2b,0xed, 0x43,0x3c,0x22,0xe0, 0x5e,0x2e,0x39,0xf7, 0x55,0x20,0x30,0xfa, 
+       0x01,0xec,0x9a,0xb7, 0x0a,0xe2,0x93,0xba, 0x17,0xf0,0x88,0xad, 0x1c,0xfe,0x81,0xa0, 
+       0x2d,0xd4,0xbe,0x83, 0x26,0xda,0xb7,0x8e, 0x3b,0xc8,0xac,0x99, 0x30,0xc6,0xa5,0x94, 
+       0x59,0x9c,0xd2,0xdf, 0x52,0x92,0xdb,0xd2, 0x4f,0x80,0xc0,0xc5, 0x44,0x8e,0xc9,0xc8, 
+       0x75,0xa4,0xf6,0xeb, 0x7e,0xaa,0xff,0xe6, 0x63,0xb8,0xe4,0xf1, 0x68,0xb6,0xed,0xfc, 
+       0xb1,0x0c,0x0a,0x67, 0xba,0x02,0x03,0x6a, 0xa7,0x10,0x18,0x7d, 0xac,0x1e,0x11,0x70, 
+       0x9d,0x34,0x2e,0x53, 0x96,0x3a,0x27,0x5e, 0x8b,0x28,0x3c,0x49, 0x80,0x26,0x35,0x44, 
+       0xe9,0x7c,0x42,0x0f, 0xe2,0x72,0x4b,0x02, 0xff,0x60,0x50,0x15, 0xf4,0x6e,0x59,0x18, 
+       0xc5,0x44,0x66,0x3b, 0xce,0x4a,0x6f,0x36, 0xd3,0x58,0x74,0x21, 0xd8,0x56,0x7d,0x2c, 
+       0x7a,0x37,0xa1,0x0c, 0x71,0x39,0xa8,0x01, 0x6c,0x2b,0xb3,0x16, 0x67,0x25,0xba,0x1b, 
+       0x56,0x0f,0x85,0x38, 0x5d,0x01,0x8c,0x35, 0x40,0x13,0x97,0x22, 0x4b,0x1d,0x9e,0x2f, 
+       0x22,0x47,0xe9,0x64, 0x29,0x49,0xe0,0x69, 0x34,0x5b,0xfb,0x7e, 0x3f,0x55,0xf2,0x73, 
+       0x0e,0x7f,0xcd,0x50, 0x05,0x71,0xc4,0x5d, 0x18,0x63,0xdf,0x4a, 0x13,0x6d,0xd6,0x47, 
+       0xca,0xd7,0x31,0xdc, 0xc1,0xd9,0x38,0xd1, 0xdc,0xcb,0x23,0xc6, 0xd7,0xc5,0x2a,0xcb, 
+       0xe6,0xef,0x15,0xe8, 0xed,0xe1,0x1c,0xe5, 0xf0,0xf3,0x07,0xf2, 0xfb,0xfd,0x0e,0xff, 
+       0x92,0xa7,0x79,0xb4, 0x99,0xa9,0x70,0xb9, 0x84,0xbb,0x6b,0xae, 0x8f,0xb5,0x62,0xa3, 
+       0xbe,0x9f,0x5d,0x80, 0xb5,0x91,0x54,0x8d, 0xa8,0x83,0x4f,0x9a, 0xa3,0x8d,0x46,0x97
+};
+
+static uint8_t U3[256][4]=
+{
+       0x00,0x00,0x00,0x00, 0x0d,0x0b,0x0e,0x09, 0x1a,0x16,0x1c,0x12, 0x17,0x1d,0x12,0x1b, 
+       0x34,0x2c,0x38,0x24, 0x39,0x27,0x36,0x2d, 0x2e,0x3a,0x24,0x36, 0x23,0x31,0x2a,0x3f, 
+       0x68,0x58,0x70,0x48, 0x65,0x53,0x7e,0x41, 0x72,0x4e,0x6c,0x5a, 0x7f,0x45,0x62,0x53, 
+       0x5c,0x74,0x48,0x6c, 0x51,0x7f,0x46,0x65, 0x46,0x62,0x54,0x7e, 0x4b,0x69,0x5a,0x77, 
+       0xd0,0xb0,0xe0,0x90, 0xdd,0xbb,0xee,0x99, 0xca,0xa6,0xfc,0x82, 0xc7,0xad,0xf2,0x8b, 
+       0xe4,0x9c,0xd8,0xb4, 0xe9,0x97,0xd6,0xbd, 0xfe,0x8a,0xc4,0xa6, 0xf3,0x81,0xca,0xaf, 
+       0xb8,0xe8,0x90,0xd8, 0xb5,0xe3,0x9e,0xd1, 0xa2,0xfe,0x8c,0xca, 0xaf,0xf5,0x82,0xc3, 
+       0x8c,0xc4,0xa8,0xfc, 0x81,0xcf,0xa6,0xf5, 0x96,0xd2,0xb4,0xee, 0x9b,0xd9,0xba,0xe7, 
+       0xbb,0x7b,0xdb,0x3b, 0xb6,0x70,0xd5,0x32, 0xa1,0x6d,0xc7,0x29, 0xac,0x66,0xc9,0x20, 
+       0x8f,0x57,0xe3,0x1f, 0x82,0x5c,0xed,0x16, 0x95,0x41,0xff,0x0d, 0x98,0x4a,0xf1,0x04, 
+       0xd3,0x23,0xab,0x73, 0xde,0x28,0xa5,0x7a, 0xc9,0x35,0xb7,0x61, 0xc4,0x3e,0xb9,0x68, 
+       0xe7,0x0f,0x93,0x57, 0xea,0x04,0x9d,0x5e, 0xfd,0x19,0x8f,0x45, 0xf0,0x12,0x81,0x4c, 
+       0x6b,0xcb,0x3b,0xab, 0x66,0xc0,0x35,0xa2, 0x71,0xdd,0x27,0xb9, 0x7c,0xd6,0x29,0xb0, 
+       0x5f,0xe7,0x03,0x8f, 0x52,0xec,0x0d,0x86, 0x45,0xf1,0x1f,0x9d, 0x48,0xfa,0x11,0x94, 
+       0x03,0x93,0x4b,0xe3, 0x0e,0x98,0x45,0xea, 0x19,0x85,0x57,0xf1, 0x14,0x8e,0x59,0xf8, 
+       0x37,0xbf,0x73,0xc7, 0x3a,0xb4,0x7d,0xce, 0x2d,0xa9,0x6f,0xd5, 0x20,0xa2,0x61,0xdc, 
+       0x6d,0xf6,0xad,0x76, 0x60,0xfd,0xa3,0x7f, 0x77,0xe0,0xb1,0x64, 0x7a,0xeb,0xbf,0x6d, 
+       0x59,0xda,0x95,0x52, 0x54,0xd1,0x9b,0x5b, 0x43,0xcc,0x89,0x40, 0x4e,0xc7,0x87,0x49, 
+       0x05,0xae,0xdd,0x3e, 0x08,0xa5,0xd3,0x37, 0x1f,0xb8,0xc1,0x2c, 0x12,0xb3,0xcf,0x25, 
+       0x31,0x82,0xe5,0x1a, 0x3c,0x89,0xeb,0x13, 0x2b,0x94,0xf9,0x08, 0x26,0x9f,0xf7,0x01, 
+       0xbd,0x46,0x4d,0xe6, 0xb0,0x4d,0x43,0xef, 0xa7,0x50,0x51,0xf4, 0xaa,0x5b,0x5f,0xfd, 
+       0x89,0x6a,0x75,0xc2, 0x84,0x61,0x7b,0xcb, 0x93,0x7c,0x69,0xd0, 0x9e,0x77,0x67,0xd9, 
+       0xd5,0x1e,0x3d,0xae, 0xd8,0x15,0x33,0xa7, 0xcf,0x08,0x21,0xbc, 0xc2,0x03,0x2f,0xb5, 
+       0xe1,0x32,0x05,0x8a, 0xec,0x39,0x0b,0x83, 0xfb,0x24,0x19,0x98, 0xf6,0x2f,0x17,0x91, 
+       0xd6,0x8d,0x76,0x4d, 0xdb,0x86,0x78,0x44, 0xcc,0x9b,0x6a,0x5f, 0xc1,0x90,0x64,0x56, 
+       0xe2,0xa1,0x4e,0x69, 0xef,0xaa,0x40,0x60, 0xf8,0xb7,0x52,0x7b, 0xf5,0xbc,0x5c,0x72, 
+       0xbe,0xd5,0x06,0x05, 0xb3,0xde,0x08,0x0c, 0xa4,0xc3,0x1a,0x17, 0xa9,0xc8,0x14,0x1e, 
+       0x8a,0xf9,0x3e,0x21, 0x87,0xf2,0x30,0x28, 0x90,0xef,0x22,0x33, 0x9d,0xe4,0x2c,0x3a, 
+       0x06,0x3d,0x96,0xdd, 0x0b,0x36,0x98,0xd4, 0x1c,0x2b,0x8a,0xcf, 0x11,0x20,0x84,0xc6, 
+       0x32,0x11,0xae,0xf9, 0x3f,0x1a,0xa0,0xf0, 0x28,0x07,0xb2,0xeb, 0x25,0x0c,0xbc,0xe2, 
+       0x6e,0x65,0xe6,0x95, 0x63,0x6e,0xe8,0x9c, 0x74,0x73,0xfa,0x87, 0x79,0x78,0xf4,0x8e, 
+       0x5a,0x49,0xde,0xb1, 0x57,0x42,0xd0,0xb8, 0x40,0x5f,0xc2,0xa3, 0x4d,0x54,0xcc,0xaa, 
+       0xda,0xf7,0x41,0xec, 0xd7,0xfc,0x4f,0xe5, 0xc0,0xe1,0x5d,0xfe, 0xcd,0xea,0x53,0xf7, 
+       0xee,0xdb,0x79,0xc8, 0xe3,0xd0,0x77,0xc1, 0xf4,0xcd,0x65,0xda, 0xf9,0xc6,0x6b,0xd3, 
+       0xb2,0xaf,0x31,0xa4, 0xbf,0xa4,0x3f,0xad, 0xa8,0xb9,0x2d,0xb6, 0xa5,0xb2,0x23,0xbf, 
+       0x86,0x83,0x09,0x80, 0x8b,0x88,0x07,0x89, 0x9c,0x95,0x15,0x92, 0x91,0x9e,0x1b,0x9b, 
+       0x0a,0x47,0xa1,0x7c, 0x07,0x4c,0xaf,0x75, 0x10,0x51,0xbd,0x6e, 0x1d,0x5a,0xb3,0x67, 
+       0x3e,0x6b,0x99,0x58, 0x33,0x60,0x97,0x51, 0x24,0x7d,0x85,0x4a, 0x29,0x76,0x8b,0x43, 
+       0x62,0x1f,0xd1,0x34, 0x6f,0x14,0xdf,0x3d, 0x78,0x09,0xcd,0x26, 0x75,0x02,0xc3,0x2f, 
+       0x56,0x33,0xe9,0x10, 0x5b,0x38,0xe7,0x19, 0x4c,0x25,0xf5,0x02, 0x41,0x2e,0xfb,0x0b, 
+       0x61,0x8c,0x9a,0xd7, 0x6c,0x87,0x94,0xde, 0x7b,0x9a,0x86,0xc5, 0x76,0x91,0x88,0xcc, 
+       0x55,0xa0,0xa2,0xf3, 0x58,0xab,0xac,0xfa, 0x4f,0xb6,0xbe,0xe1, 0x42,0xbd,0xb0,0xe8, 
+       0x09,0xd4,0xea,0x9f, 0x04,0xdf,0xe4,0x96, 0x13,0xc2,0xf6,0x8d, 0x1e,0xc9,0xf8,0x84, 
+       0x3d,0xf8,0xd2,0xbb, 0x30,0xf3,0xdc,0xb2, 0x27,0xee,0xce,0xa9, 0x2a,0xe5,0xc0,0xa0, 
+       0xb1,0x3c,0x7a,0x47, 0xbc,0x37,0x74,0x4e, 0xab,0x2a,0x66,0x55, 0xa6,0x21,0x68,0x5c, 
+       0x85,0x10,0x42,0x63, 0x88,0x1b,0x4c,0x6a, 0x9f,0x06,0x5e,0x71, 0x92,0x0d,0x50,0x78, 
+       0xd9,0x64,0x0a,0x0f, 0xd4,0x6f,0x04,0x06, 0xc3,0x72,0x16,0x1d, 0xce,0x79,0x18,0x14, 
+       0xed,0x48,0x32,0x2b, 0xe0,0x43,0x3c,0x22, 0xf7,0x5e,0x2e,0x39, 0xfa,0x55,0x20,0x30, 
+       0xb7,0x01,0xec,0x9a, 0xba,0x0a,0xe2,0x93, 0xad,0x17,0xf0,0x88, 0xa0,0x1c,0xfe,0x81, 
+       0x83,0x2d,0xd4,0xbe, 0x8e,0x26,0xda,0xb7, 0x99,0x3b,0xc8,0xac, 0x94,0x30,0xc6,0xa5, 
+       0xdf,0x59,0x9c,0xd2, 0xd2,0x52,0x92,0xdb, 0xc5,0x4f,0x80,0xc0, 0xc8,0x44,0x8e,0xc9, 
+       0xeb,0x75,0xa4,0xf6, 0xe6,0x7e,0xaa,0xff, 0xf1,0x63,0xb8,0xe4, 0xfc,0x68,0xb6,0xed, 
+       0x67,0xb1,0x0c,0x0a, 0x6a,0xba,0x02,0x03, 0x7d,0xa7,0x10,0x18, 0x70,0xac,0x1e,0x11, 
+       0x53,0x9d,0x34,0x2e, 0x5e,0x96,0x3a,0x27, 0x49,0x8b,0x28,0x3c, 0x44,0x80,0x26,0x35, 
+       0x0f,0xe9,0x7c,0x42, 0x02,0xe2,0x72,0x4b, 0x15,0xff,0x60,0x50, 0x18,0xf4,0x6e,0x59, 
+       0x3b,0xc5,0x44,0x66, 0x36,0xce,0x4a,0x6f, 0x21,0xd3,0x58,0x74, 0x2c,0xd8,0x56,0x7d, 
+       0x0c,0x7a,0x37,0xa1, 0x01,0x71,0x39,0xa8, 0x16,0x6c,0x2b,0xb3, 0x1b,0x67,0x25,0xba, 
+       0x38,0x56,0x0f,0x85, 0x35,0x5d,0x01,0x8c, 0x22,0x40,0x13,0x97, 0x2f,0x4b,0x1d,0x9e, 
+       0x64,0x22,0x47,0xe9, 0x69,0x29,0x49,0xe0, 0x7e,0x34,0x5b,0xfb, 0x73,0x3f,0x55,0xf2, 
+       0x50,0x0e,0x7f,0xcd, 0x5d,0x05,0x71,0xc4, 0x4a,0x18,0x63,0xdf, 0x47,0x13,0x6d,0xd6, 
+       0xdc,0xca,0xd7,0x31, 0xd1,0xc1,0xd9,0x38, 0xc6,0xdc,0xcb,0x23, 0xcb,0xd7,0xc5,0x2a, 
+       0xe8,0xe6,0xef,0x15, 0xe5,0xed,0xe1,0x1c, 0xf2,0xf0,0xf3,0x07, 0xff,0xfb,0xfd,0x0e, 
+       0xb4,0x92,0xa7,0x79, 0xb9,0x99,0xa9,0x70, 0xae,0x84,0xbb,0x6b, 0xa3,0x8f,0xb5,0x62, 
+       0x80,0xbe,0x9f,0x5d, 0x8d,0xb5,0x91,0x54, 0x9a,0xa8,0x83,0x4f, 0x97,0xa3,0x8d,0x46
+};
+
+static uint8_t U4[256][4]=
+{
+       0x00,0x00,0x00,0x00, 0x09,0x0d,0x0b,0x0e, 0x12,0x1a,0x16,0x1c, 0x1b,0x17,0x1d,0x12, 
+       0x24,0x34,0x2c,0x38, 0x2d,0x39,0x27,0x36, 0x36,0x2e,0x3a,0x24, 0x3f,0x23,0x31,0x2a, 
+       0x48,0x68,0x58,0x70, 0x41,0x65,0x53,0x7e, 0x5a,0x72,0x4e,0x6c, 0x53,0x7f,0x45,0x62, 
+       0x6c,0x5c,0x74,0x48, 0x65,0x51,0x7f,0x46, 0x7e,0x46,0x62,0x54, 0x77,0x4b,0x69,0x5a, 
+       0x90,0xd0,0xb0,0xe0, 0x99,0xdd,0xbb,0xee, 0x82,0xca,0xa6,0xfc, 0x8b,0xc7,0xad,0xf2, 
+       0xb4,0xe4,0x9c,0xd8, 0xbd,0xe9,0x97,0xd6, 0xa6,0xfe,0x8a,0xc4, 0xaf,0xf3,0x81,0xca, 
+       0xd8,0xb8,0xe8,0x90, 0xd1,0xb5,0xe3,0x9e, 0xca,0xa2,0xfe,0x8c, 0xc3,0xaf,0xf5,0x82, 
+       0xfc,0x8c,0xc4,0xa8, 0xf5,0x81,0xcf,0xa6, 0xee,0x96,0xd2,0xb4, 0xe7,0x9b,0xd9,0xba, 
+       0x3b,0xbb,0x7b,0xdb, 0x32,0xb6,0x70,0xd5, 0x29,0xa1,0x6d,0xc7, 0x20,0xac,0x66,0xc9, 
+       0x1f,0x8f,0x57,0xe3, 0x16,0x82,0x5c,0xed, 0x0d,0x95,0x41,0xff, 0x04,0x98,0x4a,0xf1, 
+       0x73,0xd3,0x23,0xab, 0x7a,0xde,0x28,0xa5, 0x61,0xc9,0x35,0xb7, 0x68,0xc4,0x3e,0xb9, 
+       0x57,0xe7,0x0f,0x93, 0x5e,0xea,0x04,0x9d, 0x45,0xfd,0x19,0x8f, 0x4c,0xf0,0x12,0x81, 
+       0xab,0x6b,0xcb,0x3b, 0xa2,0x66,0xc0,0x35, 0xb9,0x71,0xdd,0x27, 0xb0,0x7c,0xd6,0x29, 
+       0x8f,0x5f,0xe7,0x03, 0x86,0x52,0xec,0x0d, 0x9d,0x45,0xf1,0x1f, 0x94,0x48,0xfa,0x11, 
+       0xe3,0x03,0x93,0x4b, 0xea,0x0e,0x98,0x45, 0xf1,0x19,0x85,0x57, 0xf8,0x14,0x8e,0x59, 
+       0xc7,0x37,0xbf,0x73, 0xce,0x3a,0xb4,0x7d, 0xd5,0x2d,0xa9,0x6f, 0xdc,0x20,0xa2,0x61, 
+       0x76,0x6d,0xf6,0xad, 0x7f,0x60,0xfd,0xa3, 0x64,0x77,0xe0,0xb1, 0x6d,0x7a,0xeb,0xbf, 
+       0x52,0x59,0xda,0x95, 0x5b,0x54,0xd1,0x9b, 0x40,0x43,0xcc,0x89, 0x49,0x4e,0xc7,0x87, 
+       0x3e,0x05,0xae,0xdd, 0x37,0x08,0xa5,0xd3, 0x2c,0x1f,0xb8,0xc1, 0x25,0x12,0xb3,0xcf, 
+       0x1a,0x31,0x82,0xe5, 0x13,0x3c,0x89,0xeb, 0x08,0x2b,0x94,0xf9, 0x01,0x26,0x9f,0xf7, 
+       0xe6,0xbd,0x46,0x4d, 0xef,0xb0,0x4d,0x43, 0xf4,0xa7,0x50,0x51, 0xfd,0xaa,0x5b,0x5f, 
+       0xc2,0x89,0x6a,0x75, 0xcb,0x84,0x61,0x7b, 0xd0,0x93,0x7c,0x69, 0xd9,0x9e,0x77,0x67, 
+       0xae,0xd5,0x1e,0x3d, 0xa7,0xd8,0x15,0x33, 0xbc,0xcf,0x08,0x21, 0xb5,0xc2,0x03,0x2f, 
+       0x8a,0xe1,0x32,0x05, 0x83,0xec,0x39,0x0b, 0x98,0xfb,0x24,0x19, 0x91,0xf6,0x2f,0x17, 
+       0x4d,0xd6,0x8d,0x76, 0x44,0xdb,0x86,0x78, 0x5f,0xcc,0x9b,0x6a, 0x56,0xc1,0x90,0x64, 
+       0x69,0xe2,0xa1,0x4e, 0x60,0xef,0xaa,0x40, 0x7b,0xf8,0xb7,0x52, 0x72,0xf5,0xbc,0x5c, 
+       0x05,0xbe,0xd5,0x06, 0x0c,0xb3,0xde,0x08, 0x17,0xa4,0xc3,0x1a, 0x1e,0xa9,0xc8,0x14, 
+       0x21,0x8a,0xf9,0x3e, 0x28,0x87,0xf2,0x30, 0x33,0x90,0xef,0x22, 0x3a,0x9d,0xe4,0x2c, 
+       0xdd,0x06,0x3d,0x96, 0xd4,0x0b,0x36,0x98, 0xcf,0x1c,0x2b,0x8a, 0xc6,0x11,0x20,0x84, 
+       0xf9,0x32,0x11,0xae, 0xf0,0x3f,0x1a,0xa0, 0xeb,0x28,0x07,0xb2, 0xe2,0x25,0x0c,0xbc, 
+       0x95,0x6e,0x65,0xe6, 0x9c,0x63,0x6e,0xe8, 0x87,0x74,0x73,0xfa, 0x8e,0x79,0x78,0xf4, 
+       0xb1,0x5a,0x49,0xde, 0xb8,0x57,0x42,0xd0, 0xa3,0x40,0x5f,0xc2, 0xaa,0x4d,0x54,0xcc, 
+       0xec,0xda,0xf7,0x41, 0xe5,0xd7,0xfc,0x4f, 0xfe,0xc0,0xe1,0x5d, 0xf7,0xcd,0xea,0x53, 
+       0xc8,0xee,0xdb,0x79, 0xc1,0xe3,0xd0,0x77, 0xda,0xf4,0xcd,0x65, 0xd3,0xf9,0xc6,0x6b, 
+       0xa4,0xb2,0xaf,0x31, 0xad,0xbf,0xa4,0x3f, 0xb6,0xa8,0xb9,0x2d, 0xbf,0xa5,0xb2,0x23, 
+       0x80,0x86,0x83,0x09, 0x89,0x8b,0x88,0x07, 0x92,0x9c,0x95,0x15, 0x9b,0x91,0x9e,0x1b, 
+       0x7c,0x0a,0x47,0xa1, 0x75,0x07,0x4c,0xaf, 0x6e,0x10,0x51,0xbd, 0x67,0x1d,0x5a,0xb3, 
+       0x58,0x3e,0x6b,0x99, 0x51,0x33,0x60,0x97, 0x4a,0x24,0x7d,0x85, 0x43,0x29,0x76,0x8b, 
+       0x34,0x62,0x1f,0xd1, 0x3d,0x6f,0x14,0xdf, 0x26,0x78,0x09,0xcd, 0x2f,0x75,0x02,0xc3, 
+       0x10,0x56,0x33,0xe9, 0x19,0x5b,0x38,0xe7, 0x02,0x4c,0x25,0xf5, 0x0b,0x41,0x2e,0xfb, 
+       0xd7,0x61,0x8c,0x9a, 0xde,0x6c,0x87,0x94, 0xc5,0x7b,0x9a,0x86, 0xcc,0x76,0x91,0x88, 
+       0xf3,0x55,0xa0,0xa2, 0xfa,0x58,0xab,0xac, 0xe1,0x4f,0xb6,0xbe, 0xe8,0x42,0xbd,0xb0, 
+       0x9f,0x09,0xd4,0xea, 0x96,0x04,0xdf,0xe4, 0x8d,0x13,0xc2,0xf6, 0x84,0x1e,0xc9,0xf8, 
+       0xbb,0x3d,0xf8,0xd2, 0xb2,0x30,0xf3,0xdc, 0xa9,0x27,0xee,0xce, 0xa0,0x2a,0xe5,0xc0, 
+       0x47,0xb1,0x3c,0x7a, 0x4e,0xbc,0x37,0x74, 0x55,0xab,0x2a,0x66, 0x5c,0xa6,0x21,0x68, 
+       0x63,0x85,0x10,0x42, 0x6a,0x88,0x1b,0x4c, 0x71,0x9f,0x06,0x5e, 0x78,0x92,0x0d,0x50, 
+       0x0f,0xd9,0x64,0x0a, 0x06,0xd4,0x6f,0x04, 0x1d,0xc3,0x72,0x16, 0x14,0xce,0x79,0x18, 
+       0x2b,0xed,0x48,0x32, 0x22,0xe0,0x43,0x3c, 0x39,0xf7,0x5e,0x2e, 0x30,0xfa,0x55,0x20, 
+       0x9a,0xb7,0x01,0xec, 0x93,0xba,0x0a,0xe2, 0x88,0xad,0x17,0xf0, 0x81,0xa0,0x1c,0xfe, 
+       0xbe,0x83,0x2d,0xd4, 0xb7,0x8e,0x26,0xda, 0xac,0x99,0x3b,0xc8, 0xa5,0x94,0x30,0xc6, 
+       0xd2,0xdf,0x59,0x9c, 0xdb,0xd2,0x52,0x92, 0xc0,0xc5,0x4f,0x80, 0xc9,0xc8,0x44,0x8e, 
+       0xf6,0xeb,0x75,0xa4, 0xff,0xe6,0x7e,0xaa, 0xe4,0xf1,0x63,0xb8, 0xed,0xfc,0x68,0xb6, 
+       0x0a,0x67,0xb1,0x0c, 0x03,0x6a,0xba,0x02, 0x18,0x7d,0xa7,0x10, 0x11,0x70,0xac,0x1e, 
+       0x2e,0x53,0x9d,0x34, 0x27,0x5e,0x96,0x3a, 0x3c,0x49,0x8b,0x28, 0x35,0x44,0x80,0x26, 
+       0x42,0x0f,0xe9,0x7c, 0x4b,0x02,0xe2,0x72, 0x50,0x15,0xff,0x60, 0x59,0x18,0xf4,0x6e, 
+       0x66,0x3b,0xc5,0x44, 0x6f,0x36,0xce,0x4a, 0x74,0x21,0xd3,0x58, 0x7d,0x2c,0xd8,0x56, 
+       0xa1,0x0c,0x7a,0x37, 0xa8,0x01,0x71,0x39, 0xb3,0x16,0x6c,0x2b, 0xba,0x1b,0x67,0x25, 
+       0x85,0x38,0x56,0x0f, 0x8c,0x35,0x5d,0x01, 0x97,0x22,0x40,0x13, 0x9e,0x2f,0x4b,0x1d, 
+       0xe9,0x64,0x22,0x47, 0xe0,0x69,0x29,0x49, 0xfb,0x7e,0x34,0x5b, 0xf2,0x73,0x3f,0x55, 
+       0xcd,0x50,0x0e,0x7f, 0xc4,0x5d,0x05,0x71, 0xdf,0x4a,0x18,0x63, 0xd6,0x47,0x13,0x6d, 
+       0x31,0xdc,0xca,0xd7, 0x38,0xd1,0xc1,0xd9, 0x23,0xc6,0xdc,0xcb, 0x2a,0xcb,0xd7,0xc5, 
+       0x15,0xe8,0xe6,0xef, 0x1c,0xe5,0xed,0xe1, 0x07,0xf2,0xf0,0xf3, 0x0e,0xff,0xfb,0xfd, 
+       0x79,0xb4,0x92,0xa7, 0x70,0xb9,0x99,0xa9, 0x6b,0xae,0x84,0xbb, 0x62,0xa3,0x8f,0xb5, 
+       0x5d,0x80,0xbe,0x9f, 0x54,0x8d,0xb5,0x91, 0x4f,0x9a,0xa8,0x83, 0x46,0x97,0xa3,0x8d
+};
+
+static uint32_t rcon[30]=
+{ 
+       0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
+       0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
+       0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
+       0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
+       0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// API
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+Rijndael::Rijndael()
+{
+        m_state = Invalid;
+}
+
+Rijndael::~Rijndael()
+{
+       // nothing here
+}
+
+int Rijndael::init(Mode mode,Direction dir,const uint8_t * key,KeyLength keyLen,uint8_t * initVector)
+{
+       // Not initialized yet
+       m_state = Invalid;
+
+       // Check the mode
+       if((mode != CBC) && (mode != ECB) && (mode != CFB1))return RIJNDAEL_UNSUPPORTED_MODE;
+       m_mode = mode;
+
+       // And the direction
+       if((dir != Encrypt) && (dir != Decrypt))return RIJNDAEL_UNSUPPORTED_DIRECTION;
+       m_direction = dir;
+
+       // Allow to set an init vector
+       if(initVector)
+       {
+               // specified init vector
+               for(int i = 0;i < MAX_IV_SIZE;i++)
+               {
+                       m_initVector[i] = initVector[i];
+               }
+       } else {
+               // zero init vector
+               for(int i = 0;i < MAX_IV_SIZE;i++)
+               {
+                       m_initVector[i] = 0;
+               }
+       }
+
+       uint32_t uKeyLenInBytes;
+
+       // And check the key length
+       switch(keyLen)
+       {
+               case Key16Bytes:
+                       uKeyLenInBytes = 16;
+                       m_uRounds = 10;
+               break;
+               case Key24Bytes:
+                       uKeyLenInBytes = 24;
+                       m_uRounds = 12;
+               break;
+               case Key32Bytes:
+                       uKeyLenInBytes = 32;
+                       m_uRounds = 14;
+               break;
+               default:
+                       return RIJNDAEL_UNSUPPORTED_KEY_LENGTH;
+               break;
+       }
+       // The number of rounds is calculated as
+       // m_uRounds = (m_uKeyLenInBits / 32) + 6;
+
+       if(!key)return RIJNDAEL_BAD_KEY;
+
+       uint8_t keyMatrix[_MAX_KEY_COLUMNS][4];
+
+       for(uint32_t i = 0;i < uKeyLenInBytes;i++)keyMatrix[i >> 2][i & 3] = key[i]; 
+
+       keySched(keyMatrix);
+
+       if(m_direction == Decrypt)keyEncToDec();
+
+       m_state = Valid;
+
+       return RIJNDAEL_SUCCESS;
+}
+
+int Rijndael::blockEncrypt(const uint8_t *input,int inputLen,uint8_t *outBuffer)
+{
+       int i, k, numBlocks;
+       uint8_t block[16], iv[4][4];
+
+       if(m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
+       if(m_direction != Encrypt)return RIJNDAEL_BAD_DIRECTION;
+
+       if(input == 0 || inputLen <= 0)return 0;
+
+       numBlocks = inputLen/128;
+       
+       switch(m_mode){
+               case ECB: 
+                       for(i = numBlocks;i > 0;i--)
+                       {
+                               encrypt(input,outBuffer);
+                               input += 16;
+                               outBuffer += 16;
+                       }
+               break;
+               case CBC:
+                       ((uint32_t*)block)[0] = ((uint32_t*)m_initVector)[0] ^ ((uint32_t*)input)[0];
+                       ((uint32_t*)block)[1] = ((uint32_t*)m_initVector)[1] ^ ((uint32_t*)input)[1];
+                       ((uint32_t*)block)[2] = ((uint32_t*)m_initVector)[2] ^ ((uint32_t*)input)[2];
+                       ((uint32_t*)block)[3] = ((uint32_t*)m_initVector)[3] ^ ((uint32_t*)input)[3];
+                       encrypt(block,outBuffer);
+                       input += 16;
+                       for(i = numBlocks - 1;i > 0;i--)
+                       {
+                               ((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0];
+                               ((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1];
+                               ((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2];
+                               ((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3];
+                               outBuffer += 16;
+                               encrypt(block,outBuffer);
+                               input += 16;
+                       }
+               break;
+               case CFB1:
+#if STRICT_ALIGN 
+                       memcpy(iv,m_initVector,16); 
+#else  /* !STRICT_ALIGN */
+                       *((uint32_t*)iv[0]) = *((uint32_t*)(m_initVector   ));
+                       *((uint32_t*)iv[1]) = *((uint32_t*)(m_initVector + 4));
+                       *((uint32_t*)iv[2]) = *((uint32_t*)(m_initVector + 8));
+                       *((uint32_t*)iv[3]) = *((uint32_t*)(m_initVector +12));
+#endif /* ?STRICT_ALIGN */
+                       for(i = numBlocks; i > 0; i--)
+                       {
+                               for(k = 0; k < 128; k++)
+                               {
+                                       *((uint32_t*) block    ) = *((uint32_t*)iv[0]);
+                                       *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
+                                       *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
+                                       *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
+                                       encrypt(block,block);
+                                       outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
+                                       iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
+                                       iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
+                                       iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
+                                       iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
+                                       iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
+                                       iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
+                                       iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
+                                       iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
+                                       iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
+                                       iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
+                                       iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
+                                       iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
+                                       iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
+                                       iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
+                                       iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
+                                       iv[3][3] = (iv[3][3] << 1) | (outBuffer[k/8] >> (7-(k&7))) & 1;
+                               }
+                       }
+               break;
+               default:
+                       return -1;
+               break;
+       }
+       
+       return 128 * numBlocks;
+}
+
+int Rijndael::padEncrypt(const uint8_t *input, int inputOctets, uint8_t *outBuffer)
+{
+       int i, numBlocks, padLen;
+       uint8_t block[16], *iv;
+
+       if(m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
+       if(m_direction != Encrypt)return RIJNDAEL_NOT_INITIALIZED;
+
+       if(input == 0 || inputOctets <= 0)return 0;
+
+       numBlocks = inputOctets/16;
+
+       switch(m_mode)
+       {
+               case ECB: 
+                       for(i = numBlocks; i > 0; i--)
+                       {
+                               encrypt(input, outBuffer);
+                               input += 16;
+                               outBuffer += 16;
+                       }
+                       padLen = 16 - (inputOctets - 16*numBlocks);
+//                     assert(padLen > 0 && padLen <= 16);
+                       memcpy(block, input, 16 - padLen);
+                       memset(block + 16 - padLen, padLen, padLen);
+                       encrypt(block,outBuffer);
+               break;
+               case CBC:
+                       iv = m_initVector;
+                       for(i = numBlocks; i > 0; i--)
+                       {
+                               ((uint32_t*)block)[0] = ((uint32_t*)input)[0] ^ ((uint32_t*)iv)[0];
+                               ((uint32_t*)block)[1] = ((uint32_t*)input)[1] ^ ((uint32_t*)iv)[1];
+                               ((uint32_t*)block)[2] = ((uint32_t*)input)[2] ^ ((uint32_t*)iv)[2];
+                               ((uint32_t*)block)[3] = ((uint32_t*)input)[3] ^ ((uint32_t*)iv)[3];
+                               encrypt(block, outBuffer);
+                               iv = outBuffer;
+                               input += 16;
+                               outBuffer += 16;
+                       }
+                       padLen = 16 - (inputOctets - 16*numBlocks);
+//                     assert(padLen > 0 && padLen <= 16); // DO SOMETHING HERE ?
+                       for (i = 0; i < 16 - padLen; i++) {
+                               block[i] = input[i] ^ iv[i];
+                       }
+                       for (i = 16 - padLen; i < 16; i++) {
+                               block[i] = (uint8_t)padLen ^ iv[i];
+                       }
+                       encrypt(block,outBuffer);
+               break;
+               default:
+                       return -1;
+               break;
+       }
+       
+       return 16*(numBlocks + 1);
+}
+       
+int Rijndael::blockDecrypt(const uint8_t *input, int inputLen, uint8_t *outBuffer)
+{
+       int i, k, numBlocks;
+       uint8_t block[16], iv[4][4];
+
+       if(m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
+       if((m_mode != CFB1) && (m_direction == Encrypt))return RIJNDAEL_BAD_DIRECTION;
+
+       if (input == 0 || inputLen <= 0)return 0;
+
+       numBlocks = inputLen/128;
+
+       switch(m_mode)
+       {
+               case ECB: 
+                       for (i = numBlocks; i > 0; i--)
+                       {
+                               decrypt(input,outBuffer);
+                               input += 16;
+                               outBuffer += 16;
+                       }
+               break;
+               case CBC:
+#if STRICT_ALIGN 
+                       memcpy(iv,m_initVector,16); 
+#else
+                       *((uint32_t*)iv[0]) = *((uint32_t*)(m_initVector  ));
+                       *((uint32_t*)iv[1]) = *((uint32_t*)(m_initVector+ 4));
+                       *((uint32_t*)iv[2]) = *((uint32_t*)(m_initVector+ 8));
+                       *((uint32_t*)iv[3]) = *((uint32_t*)(m_initVector+12));
+#endif
+                       for (i = numBlocks; i > 0; i--)
+                       {
+                               decrypt(input, block);
+                               ((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]);
+                               ((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]);
+                               ((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]);
+                               ((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]);
+#if STRICT_ALIGN
+                               memcpy(iv, input, 16);
+                               memcpy(outBuf, block, 16);
+#else
+                               *((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0];
+                               *((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1];
+                               *((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2];
+                               *((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_t*)block)[3];
+#endif
+                               input += 16;
+                               outBuffer += 16;
+                       }
+                       break;
+               case CFB1:
+#if STRICT_ALIGN 
+                       memcpy(iv, m_initVector, 16); 
+#else
+                       *((uint32_t*)iv[0]) = *((uint32_t*)(m_initVector));
+                       *((uint32_t*)iv[1]) = *((uint32_t*)(m_initVector+ 4));
+                       *((uint32_t*)iv[2]) = *((uint32_t*)(m_initVector+ 8));
+                       *((uint32_t*)iv[3]) = *((uint32_t*)(m_initVector+12));
+#endif
+                       for(i = numBlocks; i > 0; i--)
+                       {
+                               for(k = 0; k < 128; k++)
+                               {
+                                       *((uint32_t*) block    ) = *((uint32_t*)iv[0]);
+                                       *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
+                                       *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
+                                       *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
+                                       encrypt(block, block);
+                                       iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
+                                       iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
+                                       iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
+                                       iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
+                                       iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
+                                       iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
+                                       iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
+                                       iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
+                                       iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
+                                       iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
+                                       iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
+                                       iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
+                                       iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
+                                       iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
+                                       iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
+                                       iv[3][3] = (iv[3][3] << 1) | (input[k/8] >> (7-(k&7))) & 1;
+                                       outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
+                               }
+                       }
+               break;
+               default:
+                       return -1;
+               break;
+       }
+       
+       return 128*numBlocks;
+}
+
+int Rijndael::padDecrypt(const uint8_t *input, int inputOctets, uint8_t *outBuffer)
+{
+       int i, numBlocks, padLen;
+       uint8_t block[16];
+       uint32_t iv[4];
+
+       if(m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
+       if(m_direction != Decrypt)return RIJNDAEL_BAD_DIRECTION;
+
+       if(input == 0 || inputOctets <= 0)return 0;
+
+       if((inputOctets % 16) != 0)return RIJNDAEL_CORRUPTED_DATA;
+
+       numBlocks = inputOctets/16;
+
+       switch(m_mode){
+               case ECB:
+                       for (i = numBlocks - 1; i > 0; i--)
+                       {
+                               decrypt(input, outBuffer);
+                               input += 16;
+                               outBuffer += 16;
+                       }
+
+                       decrypt(input, block);
+                       padLen = block[15];
+                       if (padLen >= 16)return RIJNDAEL_CORRUPTED_DATA;
+                       for(i = 16 - padLen; i < 16; i++)
+                       {
+                               if(block[i] != padLen)return RIJNDAEL_CORRUPTED_DATA;
+                       }
+                       memcpy(outBuffer, block, 16 - padLen);
+               break;  
+               case CBC:
+                       memcpy(iv, m_initVector, 16);
+                       /* all blocks but last */
+                       for (i = numBlocks - 1; i > 0; i--)
+                       {
+                               decrypt(input, block);
+                               ((uint32_t*)block)[0] ^= iv[0];
+                               ((uint32_t*)block)[1] ^= iv[1];
+                               ((uint32_t*)block)[2] ^= iv[2];
+                               ((uint32_t*)block)[3] ^= iv[3];
+                               memcpy(iv, input, 16);
+                               memcpy(outBuffer, block, 16);
+                               input += 16;
+                               outBuffer += 16;
+                       }
+                       /* last block */
+                       decrypt(input, block);
+                       ((uint32_t*)block)[0] ^= iv[0];
+                       ((uint32_t*)block)[1] ^= iv[1];
+                       ((uint32_t*)block)[2] ^= iv[2];
+                       ((uint32_t*)block)[3] ^= iv[3];
+                       padLen = block[15];
+                       if(padLen <= 0 || padLen > 16)return RIJNDAEL_CORRUPTED_DATA;
+                       for(i = 16 - padLen; i < 16; i++)
+                       {
+                               if(block[i] != padLen)return RIJNDAEL_CORRUPTED_DATA;
+                       }
+                       memcpy(outBuffer, block, 16 - padLen);
+                       break;
+               
+               default:
+                       return -1;
+               break;
+       }
+       
+       return 16*numBlocks - padLen;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// ALGORITHM
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+void Rijndael::keySched(uint8_t key[_MAX_KEY_COLUMNS][4])
+{
+       unsigned j,rconpointer = 0;
+
+       // Calculate the necessary round keys
+       // The number of calculations depends on keyBits and blockBits
+       unsigned uKeyColumns = m_uRounds - 6;
+
+       uint8_t tempKey[_MAX_KEY_COLUMNS][4];
+
+       // Copy the input key to the temporary key matrix
+
+       for(j = 0;j < uKeyColumns;j++)
+       {
+               *((uint32_t*)(tempKey[j])) = *((uint32_t*)(key[j]));
+       }
+
+       unsigned r = 0;
+       unsigned t = 0;
+
+       // copy values into round key array
+       for(j = 0;(j < uKeyColumns) && (r <= m_uRounds); )
+       {
+               for(;(j < uKeyColumns) && (t < 4); j++, t++)
+               {
+                       *((uint32_t*)m_expandedKey[r][t]) = *((uint32_t*)tempKey[j]);
+               }
+
+
+               if(t == 4)
+               {
+                       r++;
+                       t = 0;
+               }
+       }
+               
+       while(r <= m_uRounds)
+       {
+               tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]];
+               tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]];
+               tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]];
+               tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]];
+               tempKey[0][0] ^= rcon[rconpointer++];
+
+               if (uKeyColumns != 8)
+               {
+                       for(j = 1; j < uKeyColumns; j++)
+                       {
+                               *((uint32_t*)tempKey[j]) ^= *((uint32_t*)tempKey[j-1]);
+                       }
+               } else {
+                       for(j = 1; j < uKeyColumns/2; j++)
+                       {
+                               *((uint32_t*)tempKey[j]) ^= *((uint32_t*)tempKey[j-1]);
+                       }
+                       tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]];
+                       tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]];
+                       tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]];
+                       tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]];
+                       for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++)
+                       {
+                               *((uint32_t*)tempKey[j]) ^= *((uint32_t*)tempKey[j-1]);
+                       }
+               }
+               for(j = 0; (j < uKeyColumns) && (r <= m_uRounds); )
+               {
+                       for(; (j < uKeyColumns) && (t < 4); j++, t++)
+                       {
+                               *((uint32_t*)m_expandedKey[r][t]) = *((uint32_t*)tempKey[j]);
+                       }
+                       if(t == 4)
+                       {
+                               r++;
+                               t = 0;
+                       }
+               }
+       }               
+}
+
+void Rijndael::keyEncToDec()
+{
+       unsigned r;
+       uint8_t *w;
+
+       for(r = 1; r < m_uRounds; r++)
+       {
+               w = m_expandedKey[r][0];
+               *((uint32_t*)w) = *((uint32_t*)U1[w[0]]) ^ *((uint32_t*)U2[w[1]]) ^ *((uint32_t*)U3[w[2]]) ^ *((uint32_t*)U4[w[3]]);
+               w = m_expandedKey[r][1];
+               *((uint32_t*)w) = *((uint32_t*)U1[w[0]]) ^ *((uint32_t*)U2[w[1]]) ^ *((uint32_t*)U3[w[2]]) ^ *((uint32_t*)U4[w[3]]);
+               w = m_expandedKey[r][2];
+               *((uint32_t*)w) = *((uint32_t*)U1[w[0]]) ^ *((uint32_t*)U2[w[1]]) ^ *((uint32_t*)U3[w[2]]) ^ *((uint32_t*)U4[w[3]]);
+               w = m_expandedKey[r][3];
+               *((uint32_t*)w) = *((uint32_t*)U1[w[0]]) ^ *((uint32_t*)U2[w[1]]) ^ *((uint32_t*)U3[w[2]]) ^ *((uint32_t*)U4[w[3]]);
+       }
+}      
+
+void Rijndael::encrypt(const uint8_t a[16], uint8_t b[16])
+{
+       unsigned r;
+       uint8_t temp[4][4];
+
+    *((uint32_t*)temp[0]) = *((uint32_t*)(a   )) ^ *((uint32_t*)m_expandedKey[0][0]);
+    *((uint32_t*)temp[1]) = *((uint32_t*)(a+ 4)) ^ *((uint32_t*)m_expandedKey[0][1]);
+    *((uint32_t*)temp[2]) = *((uint32_t*)(a+ 8)) ^ *((uint32_t*)m_expandedKey[0][2]);
+    *((uint32_t*)temp[3]) = *((uint32_t*)(a+12)) ^ *((uint32_t*)m_expandedKey[0][3]);
+    *((uint32_t*)(b    )) = *((uint32_t*)T1[temp[0][0]])
+                                               ^ *((uint32_t*)T2[temp[1][1]])
+                                               ^ *((uint32_t*)T3[temp[2][2]]) 
+                                               ^ *((uint32_t*)T4[temp[3][3]]);
+    *((uint32_t*)(b + 4)) = *((uint32_t*)T1[temp[1][0]])
+                                               ^ *((uint32_t*)T2[temp[2][1]])
+                                               ^ *((uint32_t*)T3[temp[3][2]]) 
+                                               ^ *((uint32_t*)T4[temp[0][3]]);
+    *((uint32_t*)(b + 8)) = *((uint32_t*)T1[temp[2][0]])
+                                               ^ *((uint32_t*)T2[temp[3][1]])
+                                               ^ *((uint32_t*)T3[temp[0][2]]) 
+                                               ^ *((uint32_t*)T4[temp[1][3]]);
+    *((uint32_t*)(b +12)) = *((uint32_t*)T1[temp[3][0]])
+                                               ^ *((uint32_t*)T2[temp[0][1]])
+                                               ^ *((uint32_t*)T3[temp[1][2]]) 
+                                               ^ *((uint32_t*)T4[temp[2][3]]);
+       for(r = 1; r < m_uRounds-1; r++)
+       {
+               *((uint32_t*)temp[0]) = *((uint32_t*)(b   )) ^ *((uint32_t*)m_expandedKey[r][0]);
+               *((uint32_t*)temp[1]) = *((uint32_t*)(b+ 4)) ^ *((uint32_t*)m_expandedKey[r][1]);
+               *((uint32_t*)temp[2]) = *((uint32_t*)(b+ 8)) ^ *((uint32_t*)m_expandedKey[r][2]);
+               *((uint32_t*)temp[3]) = *((uint32_t*)(b+12)) ^ *((uint32_t*)m_expandedKey[r][3]);
+
+               *((uint32_t*)(b    )) = *((uint32_t*)T1[temp[0][0]])
+                                                       ^ *((uint32_t*)T2[temp[1][1]])
+                                                       ^ *((uint32_t*)T3[temp[2][2]]) 
+                                                       ^ *((uint32_t*)T4[temp[3][3]]);
+               *((uint32_t*)(b + 4)) = *((uint32_t*)T1[temp[1][0]])
+                                                       ^ *((uint32_t*)T2[temp[2][1]])
+                                                       ^ *((uint32_t*)T3[temp[3][2]]) 
+                                                       ^ *((uint32_t*)T4[temp[0][3]]);
+               *((uint32_t*)(b + 8)) = *((uint32_t*)T1[temp[2][0]])
+                                                       ^ *((uint32_t*)T2[temp[3][1]])
+                                                       ^ *((uint32_t*)T3[temp[0][2]]) 
+                                                       ^ *((uint32_t*)T4[temp[1][3]]);
+               *((uint32_t*)(b +12)) = *((uint32_t*)T1[temp[3][0]])
+                                                       ^ *((uint32_t*)T2[temp[0][1]])
+                                                       ^ *((uint32_t*)T3[temp[1][2]]) 
+                                                       ^ *((uint32_t*)T4[temp[2][3]]);
+       }
+       *((uint32_t*)temp[0]) = *((uint32_t*)(b   )) ^ *((uint32_t*)m_expandedKey[m_uRounds-1][0]);
+       *((uint32_t*)temp[1]) = *((uint32_t*)(b+ 4)) ^ *((uint32_t*)m_expandedKey[m_uRounds-1][1]);
+       *((uint32_t*)temp[2]) = *((uint32_t*)(b+ 8)) ^ *((uint32_t*)m_expandedKey[m_uRounds-1][2]);
+       *((uint32_t*)temp[3]) = *((uint32_t*)(b+12)) ^ *((uint32_t*)m_expandedKey[m_uRounds-1][3]);
+       b[ 0] = T1[temp[0][0]][1];
+       b[ 1] = T1[temp[1][1]][1];
+       b[ 2] = T1[temp[2][2]][1];
+       b[ 3] = T1[temp[3][3]][1];
+       b[ 4] = T1[temp[1][0]][1];
+       b[ 5] = T1[temp[2][1]][1];
+       b[ 6] = T1[temp[3][2]][1];
+       b[ 7] = T1[temp[0][3]][1];
+       b[ 8] = T1[temp[2][0]][1];
+       b[ 9] = T1[temp[3][1]][1];
+       b[10] = T1[temp[0][2]][1];
+       b[11] = T1[temp[1][3]][1];
+       b[12] = T1[temp[3][0]][1];
+       b[13] = T1[temp[0][1]][1];
+       b[14] = T1[temp[1][2]][1];
+       b[15] = T1[temp[2][3]][1];
+       *((uint32_t*)(b   )) ^= *((uint32_t*)m_expandedKey[m_uRounds][0]);
+       *((uint32_t*)(b+ 4)) ^= *((uint32_t*)m_expandedKey[m_uRounds][1]);
+       *((uint32_t*)(b+ 8)) ^= *((uint32_t*)m_expandedKey[m_uRounds][2]);
+       *((uint32_t*)(b+12)) ^= *((uint32_t*)m_expandedKey[m_uRounds][3]);
+}
+
+void Rijndael::decrypt(const uint8_t a[16], uint8_t b[16])
+{
+       int r;
+       uint8_t temp[4][4];
+       
+    *((uint32_t*)temp[0]) = *((uint32_t*)(a   )) ^ *((uint32_t*)m_expandedKey[m_uRounds][0]);
+    *((uint32_t*)temp[1]) = *((uint32_t*)(a+ 4)) ^ *((uint32_t*)m_expandedKey[m_uRounds][1]);
+    *((uint32_t*)temp[2]) = *((uint32_t*)(a+ 8)) ^ *((uint32_t*)m_expandedKey[m_uRounds][2]);
+    *((uint32_t*)temp[3]) = *((uint32_t*)(a+12)) ^ *((uint32_t*)m_expandedKey[m_uRounds][3]);
+
+    *((uint32_t*)(b   )) = *((uint32_t*)T5[temp[0][0]])
+           ^ *((uint32_t*)T6[temp[3][1]])
+           ^ *((uint32_t*)T7[temp[2][2]]) 
+           ^ *((uint32_t*)T8[temp[1][3]]);
+       *((uint32_t*)(b+ 4)) = *((uint32_t*)T5[temp[1][0]])
+           ^ *((uint32_t*)T6[temp[0][1]])
+           ^ *((uint32_t*)T7[temp[3][2]]) 
+           ^ *((uint32_t*)T8[temp[2][3]]);
+       *((uint32_t*)(b+ 8)) = *((uint32_t*)T5[temp[2][0]])
+           ^ *((uint32_t*)T6[temp[1][1]])
+           ^ *((uint32_t*)T7[temp[0][2]]) 
+           ^ *((uint32_t*)T8[temp[3][3]]);
+       *((uint32_t*)(b+12)) = *((uint32_t*)T5[temp[3][0]])
+           ^ *((uint32_t*)T6[temp[2][1]])
+           ^ *((uint32_t*)T7[temp[1][2]]) 
+           ^ *((uint32_t*)T8[temp[0][3]]);
+       for(r = m_uRounds-1; r > 1; r--)
+       {
+               *((uint32_t*)temp[0]) = *((uint32_t*)(b   )) ^ *((uint32_t*)m_expandedKey[r][0]);
+               *((uint32_t*)temp[1]) = *((uint32_t*)(b+ 4)) ^ *((uint32_t*)m_expandedKey[r][1]);
+               *((uint32_t*)temp[2]) = *((uint32_t*)(b+ 8)) ^ *((uint32_t*)m_expandedKey[r][2]);
+               *((uint32_t*)temp[3]) = *((uint32_t*)(b+12)) ^ *((uint32_t*)m_expandedKey[r][3]);
+               *((uint32_t*)(b   )) = *((uint32_t*)T5[temp[0][0]])
+           ^ *((uint32_t*)T6[temp[3][1]])
+           ^ *((uint32_t*)T7[temp[2][2]]) 
+           ^ *((uint32_t*)T8[temp[1][3]]);
+               *((uint32_t*)(b+ 4)) = *((uint32_t*)T5[temp[1][0]])
+           ^ *((uint32_t*)T6[temp[0][1]])
+           ^ *((uint32_t*)T7[temp[3][2]]) 
+           ^ *((uint32_t*)T8[temp[2][3]]);
+               *((uint32_t*)(b+ 8)) = *((uint32_t*)T5[temp[2][0]])
+           ^ *((uint32_t*)T6[temp[1][1]])
+           ^ *((uint32_t*)T7[temp[0][2]]) 
+           ^ *((uint32_t*)T8[temp[3][3]]);
+               *((uint32_t*)(b+12)) = *((uint32_t*)T5[temp[3][0]])
+           ^ *((uint32_t*)T6[temp[2][1]])
+           ^ *((uint32_t*)T7[temp[1][2]]) 
+           ^ *((uint32_t*)T8[temp[0][3]]);
+       }
+       *((uint32_t*)temp[0]) = *((uint32_t*)(b   )) ^ *((uint32_t*)m_expandedKey[1][0]);
+       *((uint32_t*)temp[1]) = *((uint32_t*)(b+ 4)) ^ *((uint32_t*)m_expandedKey[1][1]);
+       *((uint32_t*)temp[2]) = *((uint32_t*)(b+ 8)) ^ *((uint32_t*)m_expandedKey[1][2]);
+       *((uint32_t*)temp[3]) = *((uint32_t*)(b+12)) ^ *((uint32_t*)m_expandedKey[1][3]);
+       b[ 0] = S5[temp[0][0]];
+       b[ 1] = S5[temp[3][1]];
+       b[ 2] = S5[temp[2][2]];
+       b[ 3] = S5[temp[1][3]];
+       b[ 4] = S5[temp[1][0]];
+       b[ 5] = S5[temp[0][1]];
+       b[ 6] = S5[temp[3][2]];
+       b[ 7] = S5[temp[2][3]];
+       b[ 8] = S5[temp[2][0]];
+       b[ 9] = S5[temp[1][1]];
+       b[10] = S5[temp[0][2]];
+       b[11] = S5[temp[3][3]];
+       b[12] = S5[temp[3][0]];
+       b[13] = S5[temp[2][1]];
+       b[14] = S5[temp[1][2]];
+       b[15] = S5[temp[0][3]];
+       *((uint32_t*)(b   )) ^= *((uint32_t*)m_expandedKey[0][0]);
+       *((uint32_t*)(b+ 4)) ^= *((uint32_t*)m_expandedKey[0][1]);
+       *((uint32_t*)(b+ 8)) ^= *((uint32_t*)m_expandedKey[0][2]);
+       *((uint32_t*)(b+12)) ^= *((uint32_t*)m_expandedKey[0][3]);
+}
diff --git a/tools/elftosb/common/rijndael.h b/tools/elftosb/common/rijndael.h
new file mode 100644 (file)
index 0000000..79bb8ca
--- /dev/null
@@ -0,0 +1,159 @@
+#ifndef _RIJNDAEL_H_
+#define _RIJNDAEL_H_
+
+//
+// File : rijndael.h
+// Creation date : Sun Nov 5 2000 03:21:05 CEST
+// Author : Szymon Stefanek (stefanek@tin.it)
+//
+// Another implementation of the Rijndael cipher.
+// This is intended to be an easily usable library file.
+// This code is public domain.
+// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
+//
+
+//
+// Original Copyright notice:
+//
+//    rijndael-alg-fst.c   v2.4   April '2000
+//    rijndael-alg-fst.h
+//    rijndael-api-fst.c
+//    rijndael-api-fst.h
+//
+//    Optimised ANSI C code
+//
+//    authors: v1.0: Antoon Bosselaers
+//             v2.0: Vincent Rijmen, K.U.Leuven
+//             v2.3: Paulo Barreto
+//             v2.4: Vincent Rijmen, K.U.Leuven
+//
+//    This code is placed in the public domain.
+//
+
+//
+// This implementation works on 128 , 192 , 256 bit keys
+// and on 128 bit blocks
+//
+
+//
+// Example of usage:
+//
+//  // Input data
+//  unsigned char key[32];                       // The key
+//  initializeYour256BitKey();                   // Obviously initialized with sth
+//  const unsigned char * plainText = getYourPlainText(); // Your plain text
+//  int plainTextLen = strlen(plainText);        // Plain text length
+//
+//  // Encrypting
+//  Rijndael rin;
+//  unsigned char output[plainTextLen + 16];
+//
+//  rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes);
+//  // It is a good idea to check the error code
+//  int len = rin.padEncrypt(plainText,len,output);
+//  if(len >= 0)useYourEncryptedText();
+//  else encryptError(len);
+//
+//  // Decrypting: we can reuse the same object
+//  unsigned char output2[len];
+//  rin.init(Rijndael::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes));
+//  len = rin.padDecrypt(output,len,output2);
+//  if(len >= 0)useYourDecryptedText();
+//  else decryptError(len);
+//
+
+#include "stdafx.h"
+
+#define _MAX_KEY_COLUMNS (256/32)
+#define _MAX_ROUNDS      14
+#define MAX_IV_SIZE      16
+
+// We assume that unsigned int is 32 bits long.... 
+//typedef unsigned char  uint8_t;
+//typedef unsigned int   uint32_t;
+//typedef unsigned short uint16_t;
+
+// Error codes
+#define RIJNDAEL_SUCCESS 0
+#define RIJNDAEL_UNSUPPORTED_MODE -1
+#define RIJNDAEL_UNSUPPORTED_DIRECTION -2
+#define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3
+#define RIJNDAEL_BAD_KEY -4
+#define RIJNDAEL_NOT_INITIALIZED -5
+#define RIJNDAEL_BAD_DIRECTION -6
+#define RIJNDAEL_CORRUPTED_DATA -7
+
+class Rijndael
+{      
+public:
+       enum Direction { Encrypt , Decrypt };
+       enum Mode { ECB , CBC , CFB1 };
+       enum KeyLength { Key16Bytes , Key24Bytes , Key32Bytes };
+       //
+       // Creates a Rijndael cipher object
+       // You have to call init() before you can encrypt or decrypt stuff
+       //
+       Rijndael();
+       ~Rijndael();
+protected:
+       // Internal stuff
+       enum State { Valid , Invalid };
+
+       State     m_state;
+       Mode      m_mode;
+       Direction m_direction;
+       uint8_t     m_initVector[MAX_IV_SIZE];
+       uint32_t    m_uRounds;
+       uint8_t     m_expandedKey[_MAX_ROUNDS+1][4][4];
+public:
+       //////////////////////////////////////////////////////////////////////////////////////////
+       // API
+       //////////////////////////////////////////////////////////////////////////////////////////
+
+       // init(): Initializes the crypt session
+       // Returns RIJNDAEL_SUCCESS or an error code
+       // mode      : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1
+       //             You have to use the same mode for encrypting and decrypting
+       // dir       : Rijndael::Encrypt or Rijndael::Decrypt
+       //             A cipher instance works only in one direction
+       //             (Well , it could be easily modified to work in both
+       //             directions with a single init() call, but it looks
+       //             useless to me...anyway , it is a matter of generating
+       //             two expanded keys)
+       // key       : array of unsigned octets , it can be 16 , 24 or 32 bytes long
+       //             this CAN be binary data (it is not expected to be null terminated)
+       // keyLen    : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes
+       // initVector: initialization vector, you will usually use 0 here
+       int init(Mode mode,Direction dir,const uint8_t *key,KeyLength keyLen,uint8_t * initVector = 0);
+       // Encrypts the input array (can be binary data)
+       // The input array length must be a multiple of 16 bytes, the remaining part
+       // is DISCARDED.
+       // so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer
+       // Input len is in BITS!
+       // outBuffer must be at least inputLen / 8 bytes long.
+       // Returns the encrypted buffer length in BITS or an error code < 0 in case of error
+       int blockEncrypt(const uint8_t *input, int inputLen, uint8_t *outBuffer);
+       // Encrypts the input array (can be binary data)
+       // The input array can be any length , it is automatically padded on a 16 byte boundary.
+       // Input len is in BYTES!
+       // outBuffer must be at least (inputLen + 16) bytes long
+       // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error
+       int padEncrypt(const uint8_t *input, int inputOctets, uint8_t *outBuffer);
+       // Decrypts the input vector
+       // Input len is in BITS!
+       // outBuffer must be at least inputLen / 8 bytes long
+       // Returns the decrypted buffer length in BITS and an error code < 0 in case of error
+       int blockDecrypt(const uint8_t *input, int inputLen, uint8_t *outBuffer);
+       // Decrypts the input vector
+       // Input len is in BYTES!
+       // outBuffer must be at least inputLen bytes long
+       // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error
+       int padDecrypt(const uint8_t *input, int inputOctets, uint8_t *outBuffer);
+protected:
+       void keySched(uint8_t key[_MAX_KEY_COLUMNS][4]);
+       void keyEncToDec();
+       void encrypt(const uint8_t a[16], uint8_t b[16]);
+       void decrypt(const uint8_t a[16], uint8_t b[16]);
+};
+       
+#endif // _RIJNDAEL_H_
diff --git a/tools/elftosb/common/smart_ptr.h b/tools/elftosb/common/smart_ptr.h
new file mode 100644 (file)
index 0000000..dd02345
--- /dev/null
@@ -0,0 +1,232 @@
+/*
+ *  smart_ptr.h
+ *  elftosb
+ *
+ *  Created by Chris Reed on 4/18/06.
+ *  Copyright 2006 __MyCompanyName__. All rights reserved.
+ *
+ */
+#if !defined(_smart_ptr_h_)
+#define _smart_ptr_h_
+
+/*!
+ * \brief Simple, standard smart pointer class.
+ *
+ * This class only supports the single-owner paradigm.
+ */
+template <typename T>
+class smart_ptr
+{
+public:
+       typedef T data_type;
+       typedef T * ptr_type;
+       typedef const T * const_ptr_type;
+       typedef T & ref_type;
+       typedef const T & const_ref_type;
+       
+       //! Default constuctor. Initialises with no pointer set.
+       smart_ptr() : _p(0) {}
+       
+       //! This constructor takes a pointer to the object to be deleted.
+       smart_ptr(ptr_type p) : _p(p) {}
+       
+       //! Destructor. If an object (pointer) has been set, it will be deleted.
+       //! Deletes the object using safe_delete().
+       virtual ~smart_ptr() { safe_delete(); }
+       
+       //! Return the current pointer value.
+       ptr_type get() { return _p; }
+       
+       //! Return the const form of the current pointer value.
+       const_ptr_type get() const { return _p; }
+       
+       //! Change the pointer value, or set if if the default constructor was used.
+       //! If a pointer had previously been associated with the object, and \a p is
+       //! different than that previous pointer, it will be deleted before taking
+       //! ownership of \a p. If this is not desired, call reset() beforehand.
+       void set(ptr_type p)
+       {
+               if (_p && p != _p)
+               {
+                       safe_delete();
+               }
+               _p = p;
+       }
+       
+       //! Dissociates any previously set pointer value without deleting it.
+       void reset() { _p = 0; }
+       
+       //! Dissociates a previously set pointer value, deleting it at the same time.
+       void clear() { safe_delete(); }
+       
+       //! Forces immediate deletion of the object. If you are planning on using
+       //! this method, think about just using a normal pointer. It probably makes
+       //! more sense.
+       virtual void safe_delete()
+       {
+               if (_p)
+               {
+                       delete _p;
+                       _p = 0;
+               } 
+       }
+       
+       //! \name Operators
+       //@{
+       
+       //! Makes the object transparent as the template type.
+       operator ptr_type () { return _p; }
+       
+       //! Const version of the pointer operator.
+       operator const_ptr_type () const { return _p; }
+       
+       //! Makes the object transparent as a reference of the template type.
+       operator ref_type () { return *_p; }
+       
+       //! Const version of the reference operator.
+       operator const_ref_type () const { return *_p; }
+       
+       //! Returns a boolean indicating whether the object has a pointer set or not.
+       operator bool () const { return _p != 0; }
+       
+       //! To allow setting the pointer directly. Equivalent to a call to set().
+       smart_ptr<T> & operator = (const_ptr_type p)
+       {
+               set(const_cast<ptr_type>(p));
+               return *this;
+       }
+       
+       //! Another operator to allow you to treat the object just like a pointer.
+       ptr_type operator ->() { return _p; }
+       
+       //! Another operator to allow you to treat the object just like a pointer.
+       const_ptr_type operator ->() const { return _p; }
+       
+//     //! Pointer dereferencing operator.
+//     ref_type operator * () const { return *_p; }
+//     
+//     //! Const version of the pointer dereference operator.
+//     const_ref_type operator * () const { return *_p; }
+       
+       //@}
+
+protected:
+       ptr_type _p;    //!< The wrapped pointer.
+};
+
+/*!
+ * \brief Simple, standard smart pointer class that uses the array delete operator.
+ *
+ * This class only supports the single-owner paradigm.
+ *
+ * This is almost entirely a copy of smart_ptr since the final C++ specification
+ * does not allow template subclass members to access members  of the parent that
+ * do not depend on the template parameter.
+ */
+template <typename T>
+class smart_array_ptr
+{
+public:
+       typedef T data_type;
+       typedef T * ptr_type;
+       typedef const T * const_ptr_type;
+       typedef T & ref_type;
+       typedef const T & const_ref_type;
+       
+       //! Default constuctor. Initialises with no pointer set.
+       smart_array_ptr() : _p(0) {}
+       
+       //! This constructor takes a pointer to the object to be deleted.
+       smart_array_ptr(ptr_type p) : _p(p) {}
+       
+       //! Destructor. If an array has been set, it will be deleted.
+       //! Deletes the array using safe_delete().
+       virtual ~smart_array_ptr() { safe_delete(); }
+       
+       //! Return the current pointer value.
+       ptr_type get() { return _p; }
+       
+       //! Return the const form of the current pointer value.
+       const_ptr_type get() const { return _p; }
+       
+       //! Change the pointer value, or set if if the default constructor was used.
+       //! If a pointer had previously been associated with the object, and \a p is
+       //! different than that previous pointer, it will be deleted before taking
+       //! ownership of \a p. If this is not desired, call reset() beforehand.
+       void set(ptr_type p)
+       {
+               if (_p && p != _p)
+               {
+                       safe_delete();
+               }
+               _p = p;
+       }
+       
+       //! Dissociates any previously set pointer value without deleting it.
+       void reset() { _p = 0; }
+       
+       //! Dissociates a previously set pointer value, deleting it at the same time.
+       void clear() { safe_delete(); }
+       
+       //! Forces immediate deletion of the object. If you are planning on using
+       //! this method, think about just using a normal pointer. It probably makes
+       //! more sense.
+       virtual void safe_delete()
+       {
+               if (_p)
+               {
+                       delete [] _p;
+                       _p = 0;
+               } 
+       }
+       
+       //! \name Operators
+       //@{
+       
+       //! Makes the object transparent as the template type.
+       operator ptr_type () { return _p; }
+       
+       //! Const version of the pointer operator.
+       operator const_ptr_type () const { return _p; }
+       
+       //! Makes the object transparent as a reference of the template type.
+       operator ref_type () { return *_p; }
+       
+       //! Const version of the reference operator.
+       operator const_ref_type () const { return *_p; }
+       
+       //! Returns a boolean indicating whether the object has a pointer set or not.
+       operator bool () const { return _p != 0; }
+       
+       //! To allow setting the pointer directly. Equivalent to a call to set().
+       smart_array_ptr<T> & operator = (const_ptr_type p)
+       {
+               set(const_cast<ptr_type>(p));
+               return *this;
+       }
+       
+       //! Another operator to allow you to treat the object just like a pointer.
+       ptr_type operator ->() { return _p; }
+       
+       //! Another operator to allow you to treat the object just like a pointer.
+       const_ptr_type operator ->() const { return _p; }
+       
+       //! Indexing operator.
+       ref_type operator [] (unsigned index) { return _p[index]; }
+       
+       //! Indexing operator.
+       const_ref_type operator [] (unsigned index) const { return _p[index]; }
+       
+//     //! Pointer dereferencing operator.
+//     ref_type operator * () const { return *_p; }
+//     
+//     //! Const version of the pointer dereference operator.
+//     const_ref_type operator * () const { return *_p; }
+       
+       //@}
+
+protected:
+       ptr_type _p;    //!< The wrapped pointer.
+};
+
+#endif // _smart_ptr_h_
diff --git a/tools/elftosb/common/stdafx.cpp b/tools/elftosb/common/stdafx.cpp
new file mode 100644 (file)
index 0000000..9b7c4ac
--- /dev/null
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// elftosb.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/tools/elftosb/common/stdafx.h b/tools/elftosb/common/stdafx.h
new file mode 100644 (file)
index 0000000..070daa2
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef stdafx_h_
+#define stdafx_h_
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+// Default to external release.
+#ifndef SGTL_INTERNAL
+    #define SGTL_INTERNAL 0
+#endif
+
+#include <iostream>
+#include <stdexcept>
+
+#if defined(WIN32)
+//#include <tchar.h>
+
+    // define this macro for use in VC++
+    #if !defined(__LITTLE_ENDIAN__)
+       #define __LITTLE_ENDIAN__ 1
+    #endif // !defined(__LITTLE_ENDIAN__)
+#endif // defined(WIN32)
+
+#if defined(Linux)
+// For Linux systems only, types.h only defines the signed
+// integer types.  This is not professional code.
+// Update: They are defined in the header files in the more recent version of redhat enterprise gcc.
+#include <sys/types.h>
+#include <stdint.h>
+//typedef unsigned long uint32_t;
+//typedef unsigned short uint16_t;
+//typedef unsigned char uint8_t;
+
+//#define TCHAR char
+//#define _tmain main
+
+    // give a default endian in case one is not defined on Linux (it should be, though)
+    #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+       #define __LITTLE_ENDIAN__ 1
+    #endif // !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+
+#endif // defined(Linux)
+
+// gcc on Mac OS X
+#if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) )
+       #include <TargetConditionals.h>
+
+       #if defined(TARGET_RT_LITTLE_ENDIAN) && TARGET_RT_LITTLE_ENDIAN
+               #if !defined(__LITTLE_ENDIAN__)
+                       #define __LITTLE_ENDIAN__
+               #endif
+       #elif defined(TARGET_RT_BIG_ENDIAN) && TARGET_RT_BIG_ENDIAN
+               #if !defined(__BIG_ENDIAN__)
+                       #define __BIG_ENDIAN__
+               #endif
+       #endif
+#endif
+
+#if defined(WIN32) //!defined(Linux) || !defined(__GNUC__)
+// redefine missing typedefs from stdint.h or syst/types.h
+
+typedef unsigned long long uint64_t;
+typedef unsigned long uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+
+typedef long long int64_t;
+typedef long int32_t;
+typedef short int16_t;
+typedef char int8_t;
+#endif // !defined(Linux)
+
+#if !defined(TRUE)
+    #define TRUE 1
+#endif // !defined(TRUE)
+
+#if !defined(FALSE)
+    #define FALSE 0
+#endif // !defined(FALSE)
+
+#endif // stdafx_h_
diff --git a/tools/elftosb/elftosb.ccscc b/tools/elftosb/elftosb.ccscc
new file mode 100644 (file)
index 0000000..a72c5bb
--- /dev/null
@@ -0,0 +1,7 @@
+..\elftosb\elftosb.vcproj\r
+..\unittests\unittests.vcproj\r
+..\generatekeys\generatekeys.vcproj\r
+..\decrypt\decrypt.vcproj\r
+..\elftosb2\elftosb2.vcproj\r
+..\sbtool\sbtool.vcproj\r
+..\keygen\keygen.vcproj\r
diff --git a/tools/elftosb/elftosb.xcodeproj/creed.mode1 b/tools/elftosb/elftosb.xcodeproj/creed.mode1
new file mode 100644 (file)
index 0000000..aac6f7a
--- /dev/null
@@ -0,0 +1,1527 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>ActivePerspectiveName</key>
+       <string>Project</string>
+       <key>AllowedModules</key>
+       <array>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXSmartGroupTreeModule</string>
+                       <key>Name</key>
+                       <string>Groups and Files Outline View</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXNavigatorGroup</string>
+                       <key>Name</key>
+                       <string>Editor</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCTaskListModule</string>
+                       <key>Name</key>
+                       <string>Task List</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCDetailModule</string>
+                       <key>Name</key>
+                       <string>File and Smart Group Detail Viewer</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXBuildResultsModule</string>
+                       <key>Name</key>
+                       <string>Detailed Build Results Viewer</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXProjectFindModule</string>
+                       <key>Name</key>
+                       <string>Project Batch Find Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXRunSessionModule</string>
+                       <key>Name</key>
+                       <string>Run Log</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXBookmarksModule</string>
+                       <key>Name</key>
+                       <string>Bookmarks Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXClassBrowserModule</string>
+                       <key>Name</key>
+                       <string>Class Browser</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXCVSModule</string>
+                       <key>Name</key>
+                       <string>Source Code Control Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXDebugBreakpointsModule</string>
+                       <key>Name</key>
+                       <string>Debug Breakpoints Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCDockableInspector</string>
+                       <key>Name</key>
+                       <string>Inspector</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXOpenQuicklyModule</string>
+                       <key>Name</key>
+                       <string>Open Quickly Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXDebugSessionModule</string>
+                       <key>Name</key>
+                       <string>Debugger</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXDebugCLIModule</string>
+                       <key>Name</key>
+                       <string>Debug Console</string>
+               </dict>
+       </array>
+       <key>Description</key>
+       <string>DefaultDescriptionKey</string>
+       <key>DockingSystemVisible</key>
+       <false/>
+       <key>Extension</key>
+       <string>mode1</string>
+       <key>FavBarConfig</key>
+       <dict>
+               <key>PBXProjectModuleGUID</key>
+               <string>0246B7EF09C375FC009A0CA3</string>
+               <key>XCBarModuleItemNames</key>
+               <dict/>
+               <key>XCBarModuleItems</key>
+               <array/>
+       </dict>
+       <key>FirstTimeWindowDisplayed</key>
+       <false/>
+       <key>Identifier</key>
+       <string>com.apple.perspectives.project.mode1</string>
+       <key>MajorVersion</key>
+       <integer>31</integer>
+       <key>MinorVersion</key>
+       <integer>1</integer>
+       <key>Name</key>
+       <string>Default</string>
+       <key>Notifications</key>
+       <array>
+               <dict>
+                       <key>XCObserverAutoDisconnectKey</key>
+                       <true/>
+                       <key>XCObserverDefintionKey</key>
+                       <dict/>
+                       <key>XCObserverFactoryKey</key>
+                       <string>XCPerspectivesSpecificationIdentifier</string>
+                       <key>XCObserverGUIDKey</key>
+                       <string>XCObserverProjectIdentifier</string>
+                       <key>XCObserverNotificationKey</key>
+                       <string>PBXStatusBuildStateMessageNotification</string>
+                       <key>XCObserverTargetKey</key>
+                       <string>XCMainBuildResultsModuleGUID</string>
+                       <key>XCObserverTriggerKey</key>
+                       <string>awakenModuleWithObserver:</string>
+                       <key>XCObserverValidationKey</key>
+                       <dict/>
+               </dict>
+       </array>
+       <key>OpenEditors</key>
+       <array/>
+       <key>PerspectiveWidths</key>
+       <array>
+               <integer>-1</integer>
+               <integer>-1</integer>
+       </array>
+       <key>Perspectives</key>
+       <array>
+               <dict>
+                       <key>ChosenToolbarItems</key>
+                       <array>
+                               <string>active-target-popup</string>
+                               <string>active-buildstyle-popup</string>
+                               <string>action</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>buildOrClean</string>
+                               <string>build-and-runOrDebug</string>
+                               <string>com.apple.ide.PBXToolbarStopButton</string>
+                               <string>show-inspector</string>
+                               <string>get-info</string>
+                               <string>toggle-editor</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>com.apple.pbx.toolbar.searchfield</string>
+                       </array>
+                       <key>ControllerClassBaseName</key>
+                       <string></string>
+                       <key>IconName</key>
+                       <string>WindowOfProjectWithEditor</string>
+                       <key>Identifier</key>
+                       <string>perspective.project</string>
+                       <key>IsVertical</key>
+                       <false/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>ContentConfiguration</key>
+                                       <dict>
+                                               <key>PBXBottomSmartGroupGIDs</key>
+                                               <array>
+                                                       <string>1C37FBAC04509CD000000102</string>
+                                                       <string>1C37FAAC04509CD000000102</string>
+                                                       <string>1C08E77C0454961000C914BD</string>
+                                                       <string>1C37FABC05509CD000000102</string>
+                                                       <string>1C37FABC05539CD112110102</string>
+                                                       <string>E2644B35053B69B200211256</string>
+                                                       <string>1C37FABC04509CD000100104</string>
+                                                       <string>1CC0EA4004350EF90044410B</string>
+                                                       <string>1CC0EA4004350EF90041110B</string>
+                                               </array>
+                                               <key>PBXProjectModuleGUID</key>
+                                               <string>1CE0B1FE06471DED0097A5F4</string>
+                                               <key>PBXProjectModuleLabel</key>
+                                               <string>Files</string>
+                                               <key>PBXProjectStructureProvided</key>
+                                               <string>yes</string>
+                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                       <array>
+                                                               <real>22</real>
+                                                               <real>22</real>
+                                                               <real>260</real>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                       <array>
+                                                               <string>TargetStatusColumn</string>
+                                                               <string>SCMStatusColumn</string>
+                                                               <string>MainColumn</string>
+                                                       </array>
+                                               </dict>
+                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                       <array>
+                                                               <string>08FB7794FE84155DC02AAC07</string>
+                                                               <string>02FE65020BFE669B004A1450</string>
+                                                               <string>08FB7795FE84155DC02AAC07</string>
+                                                               <string>0296A45909D9AE9400F80AFF</string>
+                                                               <string>020D47700A1691F10027E24E</string>
+                                                               <string>1C37FBAC04509CD000000102</string>
+                                                               <string>1C37FAAC04509CD000000102</string>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                       <array>
+                                                               <array>
+                                                                       <integer>2</integer>
+                                                                       <integer>0</integer>
+                                                               </array>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                       <string>{{0, 0}, {304, 786}}</string>
+                                               </dict>
+                                               <key>PBXTopSmartGroupGIDs</key>
+                                               <array/>
+                                               <key>XCIncludePerspectivesSwitch</key>
+                                               <true/>
+                                               <key>XCSharingToken</key>
+                                               <string>com.apple.Xcode.GFSharingToken</string>
+                                       </dict>
+                                       <key>GeometryConfiguration</key>
+                                       <dict>
+                                               <key>Frame</key>
+                                               <string>{{0, 0}, {321, 804}}</string>
+                                               <key>GroupTreeTableConfiguration</key>
+                                               <array>
+                                                       <string>TargetStatusColumn</string>
+                                                       <real>22</real>
+                                                       <string>SCMStatusColumn</string>
+                                                       <real>22</real>
+                                                       <string>MainColumn</string>
+                                                       <real>260</real>
+                                               </array>
+                                               <key>RubberWindowFrame</key>
+                                               <string>8 33 1079 845 0 0 1440 878 </string>
+                                       </dict>
+                                       <key>Module</key>
+                                       <string>PBXSmartGroupTreeModule</string>
+                                       <key>Proportion</key>
+                                       <string>321pt</string>
+                               </dict>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B20306471E060097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>elftosb.cpp</string>
+                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                               <dict>
+                                                                       <key>Split0</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CE0B20406471E060097A5F4</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>elftosb.cpp</string>
+                                                                               <key>_historyCapacity</key>
+                                                                               <integer>0</integer>
+                                                                               <key>bookmark</key>
+                                                                               <string>0292B61F0CDA9CFD00A3A500</string>
+                                                                               <key>history</key>
+                                                                               <array>
+                                                                                       <string>02DC60CD0A87DBB90027E7F9</string>
+                                                                                       <string>021CA4400A8D2F740028326F</string>
+                                                                                       <string>021CA4420A8D2F740028326F</string>
+                                                                                       <string>021CA4480A8D2F740028326F</string>
+                                                                                       <string>02C5DBD20A926A7F003B9C11</string>
+                                                                                       <string>02C5DBDA0A926A7F003B9C11</string>
+                                                                                       <string>02C5DBDB0A926A7F003B9C11</string>
+                                                                                       <string>02C5DC310A93C14E003B9C11</string>
+                                                                                       <string>02C5DC330A93C14E003B9C11</string>
+                                                                                       <string>02C5DC350A93C14E003B9C11</string>
+                                                                                       <string>02C5DC5B0A93C796003B9C11</string>
+                                                                                       <string>02C5DCB50A93CA0A003B9C11</string>
+                                                                                       <string>02C5DCB60A93CA0A003B9C11</string>
+                                                                                       <string>02C5DD520A93D327003B9C11</string>
+                                                                                       <string>02C5DDCD0A940126003B9C11</string>
+                                                                                       <string>02C5DDCF0A940126003B9C11</string>
+                                                                                       <string>02C5DDD00A940126003B9C11</string>
+                                                                                       <string>02C5DE8D0A98B7E7003B9C11</string>
+                                                                                       <string>02CAC9B90BA06EA50020B29B</string>
+                                                                                       <string>02CAC9BA0BA06EA50020B29B</string>
+                                                                                       <string>02D1FD190BD039BF007C7450</string>
+                                                                                       <string>02D1FE2B0BD1505E007C7450</string>
+                                                                                       <string>02D1FE2E0BD1505E007C7450</string>
+                                                                                       <string>02D1FE300BD1505E007C7450</string>
+                                                                                       <string>02D1FE310BD1505E007C7450</string>
+                                                                                       <string>027EE3C30BD6930A00A6A136</string>
+                                                                                       <string>027EE3C40BD6930A00A6A136</string>
+                                                                                       <string>027EE3C50BD6930A00A6A136</string>
+                                                                                       <string>027EE3C60BD6930A00A6A136</string>
+                                                                                       <string>027EE3C70BD6930A00A6A136</string>
+                                                                                       <string>027EE3C80BD6930A00A6A136</string>
+                                                                                       <string>027EE3CE0BD6930A00A6A136</string>
+                                                                                       <string>027EE3D30BD6930A00A6A136</string>
+                                                                                       <string>027EE3D40BD6930A00A6A136</string>
+                                                                                       <string>02FE651B0BFF94B2004A1450</string>
+                                                                                       <string>02FE65200BFF94B2004A1450</string>
+                                                                                       <string>02FE65220BFF94B2004A1450</string>
+                                                                                       <string>02FE656E0C0521EA004A1450</string>
+                                                                                       <string>02FE656F0C0521EA004A1450</string>
+                                                                                       <string>02FE65710C0521EA004A1450</string>
+                                                                                       <string>02FE65730C0521EA004A1450</string>
+                                                                                       <string>02E535CF0C24641A00CBD4A5</string>
+                                                                                       <string>02E535D00C24641A00CBD4A5</string>
+                                                                                       <string>02E535D20C24641A00CBD4A5</string>
+                                                                                       <string>02E535D40C24641A00CBD4A5</string>
+                                                                                       <string>02E535D60C24641A00CBD4A5</string>
+                                                                                       <string>02E535D70C24641A00CBD4A5</string>
+                                                                                       <string>02E535D90C24641A00CBD4A5</string>
+                                                                                       <string>02E535DF0C24641A00CBD4A5</string>
+                                                                                       <string>02E535E20C24641A00CBD4A5</string>
+                                                                                       <string>02E535E30C24641A00CBD4A5</string>
+                                                                                       <string>02E535E50C24641A00CBD4A5</string>
+                                                                                       <string>02E535E70C24641A00CBD4A5</string>
+                                                                                       <string>02E535E80C24641A00CBD4A5</string>
+                                                                                       <string>02E535EB0C24641A00CBD4A5</string>
+                                                                                       <string>02E535EE0C24641A00CBD4A5</string>
+                                                                                       <string>02E535F10C24641A00CBD4A5</string>
+                                                                                       <string>02E535F20C24641A00CBD4A5</string>
+                                                                                       <string>02E535F30C24641A00CBD4A5</string>
+                                                                                       <string>02E535F70C24641A00CBD4A5</string>
+                                                                                       <string>02E5361C0C25CA2B00CBD4A5</string>
+                                                                                       <string>02E5362D0C38763700CBD4A5</string>
+                                                                                       <string>02E5362E0C38763700CBD4A5</string>
+                                                                                       <string>02E536300C38763700CBD4A5</string>
+                                                                                       <string>02E536310C38763700CBD4A5</string>
+                                                                                       <string>02E536320C38763700CBD4A5</string>
+                                                                                       <string>02E536330C38763700CBD4A5</string>
+                                                                                       <string>02E536340C38763700CBD4A5</string>
+                                                                                       <string>02E536350C38763700CBD4A5</string>
+                                                                                       <string>02E536360C38763700CBD4A5</string>
+                                                                                       <string>02E5363F0C3C4FF000CBD4A5</string>
+                                                                                       <string>024A0F200C53B9D8000317D4</string>
+                                                                                       <string>0259C9740CA30C56005285B7</string>
+                                                                                       <string>0259C9750CA30C56005285B7</string>
+                                                                                       <string>0259C9760CA30C56005285B7</string>
+                                                                                       <string>0292B60E0CDA9CFD00A3A500</string>
+                                                                                       <string>0292B60F0CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6100CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6110CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6120CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6130CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6140CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6150CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6160CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6170CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6180CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6190CDA9CFD00A3A500</string>
+                                                                               </array>
+                                                                               <key>nextStack</key>
+                                                                               <array>
+                                                                                       <string>0292B61A0CDA9CFD00A3A500</string>
+                                                                                       <string>0292B61B0CDA9CFD00A3A500</string>
+                                                                                       <string>0292B61C0CDA9CFD00A3A500</string>
+                                                                                       <string>0292B61D0CDA9CFD00A3A500</string>
+                                                                                       <string>0292B61E0CDA9CFD00A3A500</string>
+                                                                               </array>
+                                                                               <key>prevStack</key>
+                                                                               <array>
+                                                                                       <string>02DC60DC0A87DBB90027E7F9</string>
+                                                                                       <string>027EE3D80BD6930A00A6A136</string>
+                                                                                       <string>027EE3D90BD6930A00A6A136</string>
+                                                                                       <string>027EE3DA0BD6930A00A6A136</string>
+                                                                                       <string>027EE3DB0BD6930A00A6A136</string>
+                                                                                       <string>027EE3DC0BD6930A00A6A136</string>
+                                                                                       <string>027EE3DD0BD6930A00A6A136</string>
+                                                                                       <string>02FE657B0C0521EA004A1450</string>
+                                                                                       <string>02FE657C0C0521EA004A1450</string>
+                                                                                       <string>02FE65970C0A1F1A004A1450</string>
+                                                                                       <string>02E535FB0C24641A00CBD4A5</string>
+                                                                                       <string>02E535FC0C24641A00CBD4A5</string>
+                                                                                       <string>02E536200C25CA2B00CBD4A5</string>
+                                                                                       <string>02E536210C25CA2B00CBD4A5</string>
+                                                                                       <string>02E536370C38763700CBD4A5</string>
+                                                                                       <string>02E536380C38763700CBD4A5</string>
+                                                                                       <string>02E536390C38763700CBD4A5</string>
+                                                                                       <string>02E5363A0C38763700CBD4A5</string>
+                                                                                       <string>02E5363B0C38763700CBD4A5</string>
+                                                                                       <string>02E536400C3C4FF000CBD4A5</string>
+                                                                                       <string>024A0F250C53B9D8000317D4</string>
+                                                                                       <string>0259C9790CA30C56005285B7</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>SplitCount</key>
+                                                                       <string>1</string>
+                                                               </dict>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {753, 799}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>8 33 1079 845 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>799pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B20506471E060097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Detail</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 804}, {753, 0}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>8 33 1079 845 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCDetailModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>0pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>753pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCModuleDock</string>
+                               <string>PBXSmartGroupTreeModule</string>
+                               <string>XCModuleDock</string>
+                               <string>PBXNavigatorGroup</string>
+                               <string>XCDetailModule</string>
+                       </array>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>0292B6200CDA9CFD00A3A500</string>
+                               <string>1CE0B1FE06471DED0097A5F4</string>
+                               <string>0292B6210CDA9CFD00A3A500</string>
+                               <string>1CE0B20306471E060097A5F4</string>
+                               <string>1CE0B20506471E060097A5F4</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.default</string>
+               </dict>
+               <dict>
+                       <key>ControllerClassBaseName</key>
+                       <string></string>
+                       <key>IconName</key>
+                       <string>WindowOfProject</string>
+                       <key>Identifier</key>
+                       <string>perspective.morph</string>
+                       <key>IsVertical</key>
+                       <integer>0</integer>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>BecomeActive</key>
+                                       <integer>1</integer>
+                                       <key>ContentConfiguration</key>
+                                       <dict>
+                                               <key>PBXBottomSmartGroupGIDs</key>
+                                               <array>
+                                                       <string>1C37FBAC04509CD000000102</string>
+                                                       <string>1C37FAAC04509CD000000102</string>
+                                                       <string>1C08E77C0454961000C914BD</string>
+                                                       <string>1C37FABC05509CD000000102</string>
+                                                       <string>1C37FABC05539CD112110102</string>
+                                                       <string>E2644B35053B69B200211256</string>
+                                                       <string>1C37FABC04509CD000100104</string>
+                                                       <string>1CC0EA4004350EF90044410B</string>
+                                                       <string>1CC0EA4004350EF90041110B</string>
+                                               </array>
+                                               <key>PBXProjectModuleGUID</key>
+                                               <string>11E0B1FE06471DED0097A5F4</string>
+                                               <key>PBXProjectModuleLabel</key>
+                                               <string>Files</string>
+                                               <key>PBXProjectStructureProvided</key>
+                                               <string>yes</string>
+                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                       <array>
+                                                               <real>186</real>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                       <array>
+                                                               <string>MainColumn</string>
+                                                       </array>
+                                               </dict>
+                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                       <array>
+                                                               <string>29B97314FDCFA39411CA2CEA</string>
+                                                               <string>1C37FABC05509CD000000102</string>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                       <array>
+                                                               <array>
+                                                                       <integer>0</integer>
+                                                               </array>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                       <string>{{0, 0}, {186, 337}}</string>
+                                               </dict>
+                                               <key>PBXTopSmartGroupGIDs</key>
+                                               <array/>
+                                               <key>XCIncludePerspectivesSwitch</key>
+                                               <integer>1</integer>
+                                               <key>XCSharingToken</key>
+                                               <string>com.apple.Xcode.GFSharingToken</string>
+                                       </dict>
+                                       <key>GeometryConfiguration</key>
+                                       <dict>
+                                               <key>Frame</key>
+                                               <string>{{0, 0}, {203, 355}}</string>
+                                               <key>GroupTreeTableConfiguration</key>
+                                               <array>
+                                                       <string>MainColumn</string>
+                                                       <real>186</real>
+                                               </array>
+                                               <key>RubberWindowFrame</key>
+                                               <string>373 269 690 397 0 0 1440 878 </string>
+                                       </dict>
+                                       <key>Module</key>
+                                       <string>PBXSmartGroupTreeModule</string>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Morph</string>
+                       <key>PreferredWidth</key>
+                       <integer>300</integer>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCModuleDock</string>
+                               <string>PBXSmartGroupTreeModule</string>
+                       </array>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>11E0B1FE06471DED0097A5F4</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.default.short</string>
+               </dict>
+       </array>
+       <key>PerspectivesBarVisible</key>
+       <false/>
+       <key>ShelfIsVisible</key>
+       <false/>
+       <key>SourceDescription</key>
+       <string>file at '/System/Library/PrivateFrameworks/DevToolsInterface.framework/Versions/A/Resources/XCPerspectivesSpecificationMode1.xcperspec'</string>
+       <key>StatusbarIsVisible</key>
+       <true/>
+       <key>TimeStamp</key>
+       <real>215653629.27717999</real>
+       <key>ToolbarDisplayMode</key>
+       <integer>2</integer>
+       <key>ToolbarIsVisible</key>
+       <true/>
+       <key>ToolbarSizeMode</key>
+       <integer>2</integer>
+       <key>Type</key>
+       <string>Perspectives</string>
+       <key>UpdateMessage</key>
+       <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature).  You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature.  Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+       <key>WindowJustification</key>
+       <integer>5</integer>
+       <key>WindowOrderList</key>
+       <array>
+               <string>0292B6220CDA9CFD00A3A500</string>
+               <string>0292B6230CDA9CFD00A3A500</string>
+               <string>02CD175D09F6CC1200ABE650</string>
+               <string>0292B5F70CD9689200A3A500</string>
+               <string>0246B8AB09C37E4E009A0CA3</string>
+               <string>1CD10A99069EF8BA00B06720</string>
+               <string>/Users/creed/projects/sgtl/elftosb/elftosb.xcodeproj</string>
+               <string>1C0AD2B3069F1EA900FABCE6</string>
+       </array>
+       <key>WindowString</key>
+       <string>8 33 1079 845 0 0 1440 878 </string>
+       <key>WindowTools</key>
+       <array>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.build</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528F0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string></string>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {744, 0}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>566 98 744 502 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>0pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXBuildLogShowsTranscriptDefaultKey</key>
+                                                               <string>{{0, 207}, {744, 249}}</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>XCMainBuildResultsModuleGUID</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Build</string>
+                                                               <key>XCBuildResultsTrigger_Collapse</key>
+                                                               <integer>1022</integer>
+                                                               <key>XCBuildResultsTrigger_Open</key>
+                                                               <integer>1010</integer>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 5}, {744, 456}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>566 98 744 502 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXBuildResultsModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>456pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>461pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Build Results</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXBuildResultsModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>0246B8AB09C37E4E009A0CA3</string>
+                               <string>0292B5ED0CD9677200A3A500</string>
+                               <string>1CD0528F0623707200166675</string>
+                               <string>XCMainBuildResultsModuleGUID</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.build</string>
+                       <key>WindowString</key>
+                       <string>566 98 744 502 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>0246B8AB09C37E4E009A0CA3</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.debugger</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>Debugger</key>
+                                                               <dict>
+                                                                       <key>HorizontalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {307, 301}}</string>
+                                                                                       <string>{{0, 301}, {307, 480}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>VerticalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {307, 781}}</string>
+                                                                                       <string>{{307, 0}, {792, 781}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                               </dict>
+                                                               <key>LauncherConfigVersion</key>
+                                                               <string>8</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C162984064C10D400B95A72</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Debug - GLUTExamples (Underwater)</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>DebugConsoleDrawerSize</key>
+                                                               <string>{100, 120}</string>
+                                                               <key>DebugConsoleVisible</key>
+                                                               <string>None</string>
+                                                               <key>DebugConsoleWindowFrame</key>
+                                                               <string>{{200, 200}, {500, 300}}</string>
+                                                               <key>DebugSTDIOWindowFrame</key>
+                                                               <string>{{200, 200}, {500, 300}}</string>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {1099, 781}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>142 56 1099 822 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugSessionModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>781pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>781pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debugger</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugSessionModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1CD10A99069EF8BA00B06720</string>
+                               <string>0292B5F10CD9689200A3A500</string>
+                               <string>1C162984064C10D400B95A72</string>
+                               <string>0292B5F20CD9689200A3A500</string>
+                               <string>0292B5F30CD9689200A3A500</string>
+                               <string>0292B5F40CD9689200A3A500</string>
+                               <string>0292B5F50CD9689200A3A500</string>
+                               <string>0292B5F60CD9689200A3A500</string>
+                               <string>0292B5F70CD9689200A3A500</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.debug</string>
+                       <key>WindowString</key>
+                       <string>142 56 1099 822 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1CD10A99069EF8BA00B06720</string>
+                       <key>WindowToolIsVisible</key>
+                       <true/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.find</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Dock</key>
+                                                       <array>
+                                                               <dict>
+                                                                       <key>BecomeActive</key>
+                                                                       <true/>
+                                                                       <key>ContentConfiguration</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CDD528C0622207200134675</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>SourceFile.cpp</string>
+                                                                               <key>StatusBarVisibility</key>
+                                                                               <true/>
+                                                                       </dict>
+                                                                       <key>GeometryConfiguration</key>
+                                                                       <dict>
+                                                                               <key>Frame</key>
+                                                                               <string>{{0, 0}, {792, 405}}</string>
+                                                                               <key>RubberWindowFrame</key>
+                                                                               <string>387 14 792 854 0 0 1440 878 </string>
+                                                                       </dict>
+                                                                       <key>Module</key>
+                                                                       <string>PBXNavigatorGroup</string>
+                                                                       <key>Proportion</key>
+                                                                       <string>792pt</string>
+                                                               </dict>
+                                                       </array>
+                                                       <key>Proportion</key>
+                                                       <string>405pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528E0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Project Find</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 410}, {792, 403}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>387 14 792 854 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXProjectFindModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>403pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>813pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project Find</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXProjectFindModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C530D57069F1CE1000CFCEE</string>
+                               <string>02D1FD080BD039AB007C7450</string>
+                               <string>02D1FD090BD039AB007C7450</string>
+                               <string>1CDD528C0622207200134675</string>
+                               <string>1CD0528E0623707200166675</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>387 14 792 854 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C530D57069F1CE1000CFCEE</string>
+                       <key>WindowToolIsVisible</key>
+                       <true/>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>MENUSEPARATOR</string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.debuggerConsole</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C78EAAC065D492600B07095</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Debugger Console</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {440, 358}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>928 1 440 400 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugCLIModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>358pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>359pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debugger Console</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugCLIModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>02CD175D09F6CC1200ABE650</string>
+                               <string>0292B5F80CD9689200A3A500</string>
+                               <string>1C78EAAC065D492600B07095</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>928 1 440 400 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>02CD175D09F6CC1200ABE650</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.run</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>LauncherConfigVersion</key>
+                                                               <string>3</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528B0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Run</string>
+                                                               <key>Runner</key>
+                                                               <dict>
+                                                                       <key>HorizontalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {367, 168}}</string>
+                                                                                       <string>{{0, 173}, {367, 270}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>VerticalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {406, 443}}</string>
+                                                                                       <string>{{411, 0}, {517, 443}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                               </dict>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {662, 502}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>708 293 662 543 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXRunSessionModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>502pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>502pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Run Log</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXRunSessionModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C0AD2B3069F1EA900FABCE6</string>
+                               <string>0292B5F90CD9689200A3A500</string>
+                               <string>1CD0528B0623707200166675</string>
+                               <string>0292B5FA0CD9689200A3A500</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.run</string>
+                       <key>WindowString</key>
+                       <string>708 293 662 543 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C0AD2B3069F1EA900FABCE6</string>
+                       <key>WindowToolIsVisible</key>
+                       <true/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.scm</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C78EAB2065D492600B07095</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string></string>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {452, 0}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>30 547 452 308 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>0pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD052920623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>SCM Results</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 5}, {452, 262}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>30 547 452 308 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXCVSModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>262pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>267pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>SCM</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXCVSModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>02FE643D0BF793B0004A1450</string>
+                               <string>02FE643E0BF793B0004A1450</string>
+                               <string>1C78EAB2065D492600B07095</string>
+                               <string>1CD052920623707200166675</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.scm</string>
+                       <key>WindowString</key>
+                       <string>30 547 452 308 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>02FE643D0BF793B0004A1450</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.breakpoints</string>
+                       <key>IsVertical</key>
+                       <false/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXBottomSmartGroupGIDs</key>
+                                                               <array>
+                                                                       <string>1C77FABC04509CD000000102</string>
+                                                               </array>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B1FE06471DED0097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Files</string>
+                                                               <key>PBXProjectStructureProvided</key>
+                                                               <string>no</string>
+                                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                                               <dict>
+                                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                                       <array>
+                                                                               <real>168</real>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                                       <array>
+                                                                               <string>MainColumn</string>
+                                                                       </array>
+                                                               </dict>
+                                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                                               <dict>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                                       <array>
+                                                                               <string>1C77FABC04509CD000000102</string>
+                                                                               <string>1C3E0DCA080725EA00A55177</string>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                                       <array>
+                                                                               <array>
+                                                                                       <integer>0</integer>
+                                                                               </array>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                                       <string>{{0, 0}, {168, 350}}</string>
+                                                               </dict>
+                                                               <key>PBXTopSmartGroupGIDs</key>
+                                                               <array/>
+                                                               <key>XCIncludePerspectivesSwitch</key>
+                                                               <false/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {185, 368}}</string>
+                                                               <key>GroupTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>MainColumn</string>
+                                                                       <real>168</real>
+                                                               </array>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>28 375 744 409 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXSmartGroupTreeModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>185pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CA1AED706398EBD00589147</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Detail</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{190, 0}, {554, 368}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>28 375 744 409 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCDetailModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>554pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>368pt</string>
+                               </dict>
+                       </array>
+                       <key>MajorVersion</key>
+                       <integer>2</integer>
+                       <key>MinorVersion</key>
+                       <integer>0</integer>
+                       <key>Name</key>
+                       <string>Breakpoints</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXSmartGroupTreeModule</string>
+                               <string>XCDetailModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>027EE4730BD6D24700A6A136</string>
+                               <string>027EE4740BD6D24700A6A136</string>
+                               <string>1CE0B1FE06471DED0097A5F4</string>
+                               <string>1CA1AED706398EBD00589147</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.breakpoints</string>
+                       <key>WindowString</key>
+                       <string>28 375 744 409 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>027EE4730BD6D24700A6A136</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.debugAnimator</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>02E39A7909F721C80055992A</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string></string>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {700, 459}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>36 211 700 500 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>459pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>459pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debug Visualizer</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXNavigatorGroup</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>027EE4660BD6CDCB00A6A136</string>
+                               <string>027EE4670BD6CDCB00A6A136</string>
+                               <string>02E39A7909F721C80055992A</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.debugAnimator</string>
+                       <key>WindowString</key>
+                       <string>36 211 700 500 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>027EE4660BD6CDCB00A6A136</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.bookmarks</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>PBXBookmarksModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Bookmarks</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXBookmarksModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <integer>0</integer>
+                       <key>WindowString</key>
+                       <string>538 42 401 187 0 0 1280 1002 </string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.classBrowser</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>OptionsSetName</key>
+                                                               <string>Hierarchy, project classes</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CA6456E063B45B4001379D8</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Class Browser - RijndaelCBCMAC</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>ClassesFrame</key>
+                                                               <string>{{0, 0}, {759, 298}}</string>
+                                                               <key>ClassesTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>PBXClassNameColumnIdentifier</string>
+                                                                       <real>208</real>
+                                                                       <string>PBXClassBookColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                               </array>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {1011, 802}}</string>
+                                                               <key>MembersFrame</key>
+                                                               <string>{{0, 303}, {759, 499}}</string>
+                                                               <key>MembersTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>PBXMemberTypeIconColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                                       <string>PBXMemberNameColumnIdentifier</string>
+                                                                       <real>216</real>
+                                                                       <string>PBXMemberTypeColumnIdentifier</string>
+                                                                       <real>482</real>
+                                                                       <string>PBXMemberBookColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                               </array>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>159 56 1011 822 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXClassBrowserModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>802pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>802pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Class Browser</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXClassBrowserModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <false/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C0AD2AF069F1E9B00FABCE6</string>
+                               <string>027EE3B20BD5CE9600A6A136</string>
+                               <string>1CA6456E063B45B4001379D8</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.classbrowser</string>
+                       <key>WindowString</key>
+                       <string>159 56 1011 822 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C0AD2AF069F1E9B00FABCE6</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+       </array>
+</dict>
+</plist>
diff --git a/tools/elftosb/elftosb.xcodeproj/creed.mode1v3 b/tools/elftosb/elftosb.xcodeproj/creed.mode1v3
new file mode 100644 (file)
index 0000000..55efe7c
--- /dev/null
@@ -0,0 +1,1569 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>ActivePerspectiveName</key>
+       <string>Project</string>
+       <key>AllowedModules</key>
+       <array>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXSmartGroupTreeModule</string>
+                       <key>Name</key>
+                       <string>Groups and Files Outline View</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXNavigatorGroup</string>
+                       <key>Name</key>
+                       <string>Editor</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCTaskListModule</string>
+                       <key>Name</key>
+                       <string>Task List</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCDetailModule</string>
+                       <key>Name</key>
+                       <string>File and Smart Group Detail Viewer</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXBuildResultsModule</string>
+                       <key>Name</key>
+                       <string>Detailed Build Results Viewer</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXProjectFindModule</string>
+                       <key>Name</key>
+                       <string>Project Batch Find Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCProjectFormatConflictsModule</string>
+                       <key>Name</key>
+                       <string>Project Format Conflicts List</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXBookmarksModule</string>
+                       <key>Name</key>
+                       <string>Bookmarks Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXClassBrowserModule</string>
+                       <key>Name</key>
+                       <string>Class Browser</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXCVSModule</string>
+                       <key>Name</key>
+                       <string>Source Code Control Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXDebugBreakpointsModule</string>
+                       <key>Name</key>
+                       <string>Debug Breakpoints Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCDockableInspector</string>
+                       <key>Name</key>
+                       <string>Inspector</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>PBXOpenQuicklyModule</string>
+                       <key>Name</key>
+                       <string>Open Quickly Tool</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXDebugSessionModule</string>
+                       <key>Name</key>
+                       <string>Debugger</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>1</string>
+                       <key>Module</key>
+                       <string>PBXDebugCLIModule</string>
+                       <key>Name</key>
+                       <string>Debug Console</string>
+               </dict>
+               <dict>
+                       <key>BundleLoadPath</key>
+                       <string></string>
+                       <key>MaxInstances</key>
+                       <string>n</string>
+                       <key>Module</key>
+                       <string>XCSnapshotModule</string>
+                       <key>Name</key>
+                       <string>Snapshots Tool</string>
+               </dict>
+       </array>
+       <key>Description</key>
+       <string>DefaultDescriptionKey</string>
+       <key>DockingSystemVisible</key>
+       <false/>
+       <key>Extension</key>
+       <string>mode1v3</string>
+       <key>FavBarConfig</key>
+       <dict>
+               <key>PBXProjectModuleGUID</key>
+               <string>025881920CF13C0400681C7E</string>
+               <key>XCBarModuleItemNames</key>
+               <dict/>
+               <key>XCBarModuleItems</key>
+               <array/>
+       </dict>
+       <key>FirstTimeWindowDisplayed</key>
+       <false/>
+       <key>Identifier</key>
+       <string>com.apple.perspectives.project.mode1v3</string>
+       <key>MajorVersion</key>
+       <integer>33</integer>
+       <key>MinorVersion</key>
+       <integer>0</integer>
+       <key>Name</key>
+       <string>Default</string>
+       <key>Notifications</key>
+       <array>
+               <dict>
+                       <key>XCObserverAutoDisconnectKey</key>
+                       <true/>
+                       <key>XCObserverDefintionKey</key>
+                       <dict/>
+                       <key>XCObserverFactoryKey</key>
+                       <string>XCPerspectivesSpecificationIdentifier</string>
+                       <key>XCObserverGUIDKey</key>
+                       <string>XCObserverProjectIdentifier</string>
+                       <key>XCObserverNotificationKey</key>
+                       <string>PBXStatusBuildStateMessageNotification</string>
+                       <key>XCObserverTargetKey</key>
+                       <string>XCMainBuildResultsModuleGUID</string>
+                       <key>XCObserverTriggerKey</key>
+                       <string>awakenModuleWithObserver:</string>
+                       <key>XCObserverValidationKey</key>
+                       <dict/>
+               </dict>
+       </array>
+       <key>OpenEditors</key>
+       <array/>
+       <key>PerspectiveWidths</key>
+       <array>
+               <integer>1079</integer>
+               <integer>300</integer>
+       </array>
+       <key>Perspectives</key>
+       <array>
+               <dict>
+                       <key>ChosenToolbarItems</key>
+                       <array>
+                               <string>active-combo-popup</string>
+                               <string>action</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>debugger-enable-breakpoints</string>
+                               <string>build-and-go</string>
+                               <string>buildOrClean</string>
+                               <string>com.apple.ide.PBXToolbarStopButton</string>
+                               <string>get-info</string>
+                               <string>show-inspector</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>servicesModuleCVS</string>
+                               <string>servicesModuledebug</string>
+                               <string>servicesModulebreakpoints</string>
+                               <string>servicesModulefind</string>
+                               <string>com.apple.pbx.toolbar.searchfield</string>
+                       </array>
+                       <key>ControllerClassBaseName</key>
+                       <string></string>
+                       <key>IconName</key>
+                       <string>WindowOfProjectWithEditor</string>
+                       <key>Identifier</key>
+                       <string>perspective.project</string>
+                       <key>IsVertical</key>
+                       <false/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>ContentConfiguration</key>
+                                       <dict>
+                                               <key>PBXBottomSmartGroupGIDs</key>
+                                               <array>
+                                                       <string>1C37FBAC04509CD000000102</string>
+                                                       <string>1C37FAAC04509CD000000102</string>
+                                                       <string>1C37FABC05509CD000000102</string>
+                                                       <string>1C37FABC05539CD112110102</string>
+                                                       <string>E2644B35053B69B200211256</string>
+                                                       <string>1C37FABC04509CD000100104</string>
+                                                       <string>1CC0EA4004350EF90044410B</string>
+                                                       <string>1CC0EA4004350EF90041110B</string>
+                                               </array>
+                                               <key>PBXProjectModuleGUID</key>
+                                               <string>1CE0B1FE06471DED0097A5F4</string>
+                                               <key>PBXProjectModuleLabel</key>
+                                               <string>Files</string>
+                                               <key>PBXProjectStructureProvided</key>
+                                               <string>yes</string>
+                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                       <array>
+                                                               <real>22</real>
+                                                               <real>22</real>
+                                                               <real>260</real>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                       <array>
+                                                               <string>TargetStatusColumn</string>
+                                                               <string>SCMStatusColumn</string>
+                                                               <string>MainColumn</string>
+                                                       </array>
+                                               </dict>
+                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                       <array>
+                                                               <string>08FB7794FE84155DC02AAC07</string>
+                                                               <string>02FE65020BFE669B004A1450</string>
+                                                               <string>08FB7795FE84155DC02AAC07</string>
+                                                               <string>0296A45909D9AE9400F80AFF</string>
+                                                               <string>02D46C140FED492C00E65706</string>
+                                                               <string>020D47700A1691F10027E24E</string>
+                                                               <string>1C37FAAC04509CD000000102</string>
+                                                               <string>1C37FABC05509CD000000102</string>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                       <array>
+                                                               <array>
+                                                                       <integer>26</integer>
+                                                                       <integer>11</integer>
+                                                                       <integer>7</integer>
+                                                                       <integer>0</integer>
+                                                               </array>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                       <string>{{0, 44}, {304, 1080}}</string>
+                                               </dict>
+                                               <key>PBXTopSmartGroupGIDs</key>
+                                               <array/>
+                                               <key>XCIncludePerspectivesSwitch</key>
+                                               <true/>
+                                               <key>XCSharingToken</key>
+                                               <string>com.apple.Xcode.GFSharingToken</string>
+                                       </dict>
+                                       <key>GeometryConfiguration</key>
+                                       <dict>
+                                               <key>Frame</key>
+                                               <string>{{0, 0}, {321, 1098}}</string>
+                                               <key>GroupTreeTableConfiguration</key>
+                                               <array>
+                                                       <string>TargetStatusColumn</string>
+                                                       <real>22</real>
+                                                       <string>SCMStatusColumn</string>
+                                                       <real>22</real>
+                                                       <string>MainColumn</string>
+                                                       <real>260</real>
+                                               </array>
+                                               <key>RubberWindowFrame</key>
+                                               <string>19 39 1197 1139 0 0 1920 1178 </string>
+                                       </dict>
+                                       <key>Module</key>
+                                       <string>PBXSmartGroupTreeModule</string>
+                                       <key>Proportion</key>
+                                       <string>321pt</string>
+                               </dict>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B20306471E060097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>elftosb.cpp</string>
+                                                               <key>PBXSplitModuleInNavigatorKey</key>
+                                                               <dict>
+                                                                       <key>Split0</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CE0B20406471E060097A5F4</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>elftosb.cpp</string>
+                                                                               <key>_historyCapacity</key>
+                                                                               <integer>0</integer>
+                                                                               <key>bookmark</key>
+                                                                               <string>022B47721218CDBF00A74F96</string>
+                                                                               <key>history</key>
+                                                                               <array>
+                                                                                       <string>021CA4400A8D2F740028326F</string>
+                                                                                       <string>021CA4420A8D2F740028326F</string>
+                                                                                       <string>02C5DBD20A926A7F003B9C11</string>
+                                                                                       <string>02C5DBDB0A926A7F003B9C11</string>
+                                                                                       <string>02C5DC310A93C14E003B9C11</string>
+                                                                                       <string>02C5DC330A93C14E003B9C11</string>
+                                                                                       <string>02C5DC350A93C14E003B9C11</string>
+                                                                                       <string>02C5DCB50A93CA0A003B9C11</string>
+                                                                                       <string>02C5DD520A93D327003B9C11</string>
+                                                                                       <string>02C5DDCD0A940126003B9C11</string>
+                                                                                       <string>02C5DDCF0A940126003B9C11</string>
+                                                                                       <string>02CAC9BA0BA06EA50020B29B</string>
+                                                                                       <string>02D1FD190BD039BF007C7450</string>
+                                                                                       <string>02D1FE2E0BD1505E007C7450</string>
+                                                                                       <string>027EE3C30BD6930A00A6A136</string>
+                                                                                       <string>027EE3C80BD6930A00A6A136</string>
+                                                                                       <string>02FE651B0BFF94B2004A1450</string>
+                                                                                       <string>02E535CF0C24641A00CBD4A5</string>
+                                                                                       <string>02E535D00C24641A00CBD4A5</string>
+                                                                                       <string>02E535D20C24641A00CBD4A5</string>
+                                                                                       <string>02E535D40C24641A00CBD4A5</string>
+                                                                                       <string>02E535D70C24641A00CBD4A5</string>
+                                                                                       <string>02E535D90C24641A00CBD4A5</string>
+                                                                                       <string>02E535F10C24641A00CBD4A5</string>
+                                                                                       <string>02E5362D0C38763700CBD4A5</string>
+                                                                                       <string>02E536320C38763700CBD4A5</string>
+                                                                                       <string>02E536360C38763700CBD4A5</string>
+                                                                                       <string>02E5363F0C3C4FF000CBD4A5</string>
+                                                                                       <string>024A0F200C53B9D8000317D4</string>
+                                                                                       <string>0292B60E0CDA9CFD00A3A500</string>
+                                                                                       <string>0292B60F0CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6100CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6170CDA9CFD00A3A500</string>
+                                                                                       <string>0292B6180CDA9CFD00A3A500</string>
+                                                                                       <string>0258817C0CF13C0400681C7E</string>
+                                                                                       <string>025881810CF13C0400681C7E</string>
+                                                                                       <string>025881850CF13C0400681C7E</string>
+                                                                                       <string>025881860CF13C0400681C7E</string>
+                                                                                       <string>025881890CF13C0400681C7E</string>
+                                                                                       <string>0234AF900D69029300A16BFF</string>
+                                                                                       <string>0234AF910D69029300A16BFF</string>
+                                                                                       <string>0234AF920D69029300A16BFF</string>
+                                                                                       <string>0234AF930D69029300A16BFF</string>
+                                                                                       <string>0234AF950D69029300A16BFF</string>
+                                                                                       <string>0234AF970D69029300A16BFF</string>
+                                                                                       <string>0234AF9A0D69029300A16BFF</string>
+                                                                                       <string>0234AF9C0D69029300A16BFF</string>
+                                                                                       <string>0234AF9D0D69029300A16BFF</string>
+                                                                                       <string>0234AFA00D69029300A16BFF</string>
+                                                                                       <string>02D46C3F0FED5C3600E65706</string>
+                                                                                       <string>02D46C690FED5F4B00E65706</string>
+                                                                                       <string>02D46D1A0FED80BF00E65706</string>
+                                                                                       <string>02D795420FF00D8B00C1C5DF</string>
+                                                                                       <string>02D795430FF00D8B00C1C5DF</string>
+                                                                                       <string>02D795450FF00D8B00C1C5DF</string>
+                                                                                       <string>02D795460FF00D8B00C1C5DF</string>
+                                                                                       <string>02D795470FF00D8B00C1C5DF</string>
+                                                                                       <string>02D795480FF00D8B00C1C5DF</string>
+                                                                                       <string>02D795490FF00D8B00C1C5DF</string>
+                                                                                       <string>02D7954D0FF00D8B00C1C5DF</string>
+                                                                                       <string>02D6133010F28A6500B7DF2F</string>
+                                                                                       <string>02D6138C10F3E89000B7DF2F</string>
+                                                                                       <string>02D6138E10F3E89000B7DF2F</string>
+                                                                                       <string>02D6139110F3E89000B7DF2F</string>
+                                                                                       <string>02D6139510F3E89000B7DF2F</string>
+                                                                                       <string>02D6139710F3E89000B7DF2F</string>
+                                                                                       <string>02D6139810F3E89000B7DF2F</string>
+                                                                                       <string>02D6139910F3E89000B7DF2F</string>
+                                                                                       <string>022B461D1216FEA700A74F96</string>
+                                                                                       <string>022B468B1218659A00A74F96</string>
+                                                                                       <string>022B468D1218659A00A74F96</string>
+                                                                                       <string>022B468E1218659A00A74F96</string>
+                                                                                       <string>022B468F1218659A00A74F96</string>
+                                                                                       <string>022B46901218659A00A74F96</string>
+                                                                                       <string>022B46921218659A00A74F96</string>
+                                                                                       <string>022B46931218659A00A74F96</string>
+                                                                                       <string>022B46941218659A00A74F96</string>
+                                                                                       <string>022B46951218659A00A74F96</string>
+                                                                                       <string>022B47281218C17F00A74F96</string>
+                                                                                       <string>022B47391218C46A00A74F96</string>
+                                                                                       <string>022B473A1218C46A00A74F96</string>
+                                                                                       <string>022B474B1218CA9A00A74F96</string>
+                                                                                       <string>022B474C1218CA9A00A74F96</string>
+                                                                                       <string>022B476F1218CDBF00A74F96</string>
+                                                                                       <string>022B47701218CDBF00A74F96</string>
+                                                                                       <string>022B47711218CDBF00A74F96</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>SplitCount</key>
+                                                                       <string>1</string>
+                                                               </dict>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {871, 1093}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>19 39 1197 1139 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>1093pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B20506471E060097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Detail</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 1098}, {871, 0}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>19 39 1197 1139 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCDetailModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>0pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>871pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCModuleDock</string>
+                               <string>PBXSmartGroupTreeModule</string>
+                               <string>XCModuleDock</string>
+                               <string>PBXNavigatorGroup</string>
+                               <string>XCDetailModule</string>
+                       </array>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>022B46261216FEA700A74F96</string>
+                               <string>1CE0B1FE06471DED0097A5F4</string>
+                               <string>022B46271216FEA700A74F96</string>
+                               <string>1CE0B20306471E060097A5F4</string>
+                               <string>1CE0B20506471E060097A5F4</string>
+                       </array>
+                       <key>ToolbarConfigUserDefaultsMinorVersion</key>
+                       <string>2</string>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.defaultV3</string>
+               </dict>
+               <dict>
+                       <key>ChosenToolbarItems</key>
+                       <array>
+                               <string>XCToolbarPerspectiveControl</string>
+                               <string>NSToolbarSeparatorItem</string>
+                               <string>buildOrClean</string>
+                               <string>build-and-goOrGo</string>
+                               <string>debugger-enable-breakpoints</string>
+                               <string>com.apple.ide.PBXToolbarStopButton</string>
+                               <string>NSToolbarFlexibleSpaceItem</string>
+                               <string>get-info</string>
+                       </array>
+                       <key>ControllerClassBaseName</key>
+                       <string></string>
+                       <key>IconName</key>
+                       <string>WindowOfProject</string>
+                       <key>Identifier</key>
+                       <string>perspective.morph</string>
+                       <key>IsVertical</key>
+                       <false/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>ContentConfiguration</key>
+                                       <dict>
+                                               <key>PBXBottomSmartGroupGIDs</key>
+                                               <array>
+                                                       <string>1C37FBAC04509CD000000102</string>
+                                                       <string>1C37FAAC04509CD000000102</string>
+                                                       <string>1C08E77C0454961000C914BD</string>
+                                                       <string>1C37FABC05509CD000000102</string>
+                                                       <string>1C37FABC05539CD112110102</string>
+                                                       <string>E2644B35053B69B200211256</string>
+                                                       <string>1C37FABC04509CD000100104</string>
+                                                       <string>1CC0EA4004350EF90044410B</string>
+                                                       <string>1CC0EA4004350EF90041110B</string>
+                                               </array>
+                                               <key>PBXProjectModuleGUID</key>
+                                               <string>11E0B1FE06471DED0097A5F4</string>
+                                               <key>PBXProjectModuleLabel</key>
+                                               <string>Files</string>
+                                               <key>PBXProjectStructureProvided</key>
+                                               <string>yes</string>
+                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                       <array>
+                                                               <real>22</real>
+                                                               <real>22</real>
+                                                               <real>239</real>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                       <array>
+                                                               <string>TargetStatusColumn</string>
+                                                               <string>SCMStatusColumn</string>
+                                                               <string>MainColumn</string>
+                                                       </array>
+                                               </dict>
+                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                               <dict>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                       <array>
+                                                               <string>08FB7794FE84155DC02AAC07</string>
+                                                               <string>02FE65020BFE669B004A1450</string>
+                                                               <string>08FB7795FE84155DC02AAC07</string>
+                                                               <string>0296A45909D9AE9400F80AFF</string>
+                                                               <string>020D47700A1691F10027E24E</string>
+                                                               <string>1C37FBAC04509CD000000102</string>
+                                                               <string>1C37FAAC04509CD000000102</string>
+                                                               <string>1C37FABC05509CD000000102</string>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                       <array>
+                                                               <array>
+                                                                       <integer>42</integer>
+                                                                       <integer>7</integer>
+                                                                       <integer>0</integer>
+                                                               </array>
+                                                       </array>
+                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                       <string>{{0, 0}, {283, 782}}</string>
+                                               </dict>
+                                               <key>PBXTopSmartGroupGIDs</key>
+                                               <array/>
+                                               <key>XCIncludePerspectivesSwitch</key>
+                                               <true/>
+                                               <key>XCSharingToken</key>
+                                               <string>com.apple.Xcode.GFSharingToken</string>
+                                       </dict>
+                                       <key>GeometryConfiguration</key>
+                                       <dict>
+                                               <key>Frame</key>
+                                               <string>{{0, 0}, {300, 800}}</string>
+                                               <key>GroupTreeTableConfiguration</key>
+                                               <array>
+                                                       <string>TargetStatusColumn</string>
+                                                       <real>22</real>
+                                                       <string>SCMStatusColumn</string>
+                                                       <real>22</real>
+                                                       <string>MainColumn</string>
+                                                       <real>239</real>
+                                               </array>
+                                       </dict>
+                                       <key>Module</key>
+                                       <string>PBXSmartGroupTreeModule</string>
+                                       <key>Proportion</key>
+                                       <string>300pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Morph</string>
+                       <key>PreferredWidth</key>
+                       <integer>300</integer>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCModuleDock</string>
+                               <string>PBXSmartGroupTreeModule</string>
+                       </array>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>025881910CF13C0400681C7E</string>
+                               <string>11E0B1FE06471DED0097A5F4</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.default.shortV3</string>
+               </dict>
+       </array>
+       <key>PerspectivesBarVisible</key>
+       <false/>
+       <key>ShelfIsVisible</key>
+       <false/>
+       <key>StatusbarIsVisible</key>
+       <true/>
+       <key>TimeStamp</key>
+       <real>303615423.96806198</real>
+       <key>ToolbarDisplayMode</key>
+       <integer>2</integer>
+       <key>ToolbarIsVisible</key>
+       <true/>
+       <key>ToolbarSizeMode</key>
+       <integer>1</integer>
+       <key>Type</key>
+       <string>Perspectives</string>
+       <key>UpdateMessage</key>
+       <string>The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature).  You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature.  Do you wish to update to the latest Workspace defaults for project '%@'?</string>
+       <key>WindowJustification</key>
+       <integer>5</integer>
+       <key>WindowOrderList</key>
+       <array>
+               <string>022B46991218659A00A74F96</string>
+               <string>022B469A1218659A00A74F96</string>
+               <string>02D46D160FED80AF00E65706</string>
+               <string>1CD10A99069EF8BA00B06720</string>
+               <string>1C530D57069F1CE1000CFCEE</string>
+               <string>025880F00CEE3D1200681C7E</string>
+               <string>/Users/creed/projects/fsl/fromsvr/elftosb/elftosb.xcodeproj</string>
+               <string>1C78EAAD065D492600B07095</string>
+       </array>
+       <key>WindowString</key>
+       <string>19 39 1197 1139 0 0 1920 1178 </string>
+       <key>WindowToolsV3</key>
+       <array>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.build</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528F0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>ElftosbAST.cpp</string>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {744, 171}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>1048 148 744 502 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>171pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>XCMainBuildResultsModuleGUID</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Build Results</string>
+                                                               <key>XCBuildResultsTrigger_Collapse</key>
+                                                               <integer>1022</integer>
+                                                               <key>XCBuildResultsTrigger_Open</key>
+                                                               <integer>1010</integer>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 176}, {744, 285}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>1048 148 744 502 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXBuildResultsModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>285pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>461pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Build Results</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXBuildResultsModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>025880F00CEE3D1200681C7E</string>
+                               <string>022B461512136A6A00A74F96</string>
+                               <string>1CD0528F0623707200166675</string>
+                               <string>XCMainBuildResultsModuleGUID</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.buildV3</string>
+                       <key>WindowString</key>
+                       <string>1048 148 744 502 0 0 1920 1178 </string>
+                       <key>WindowToolGUID</key>
+                       <string>025880F00CEE3D1200681C7E</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.debugger</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>Debugger</key>
+                                                               <dict>
+                                                                       <key>HorizontalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {308, 302}}</string>
+                                                                                       <string>{{0, 302}, {308, 479}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                                       <key>VerticalSplitView</key>
+                                                                       <dict>
+                                                                               <key>_collapsingFrameDimension</key>
+                                                                               <real>0.0</real>
+                                                                               <key>_indexOfCollapsedView</key>
+                                                                               <integer>0</integer>
+                                                                               <key>_percentageOfCollapsedView</key>
+                                                                               <real>0.0</real>
+                                                                               <key>isCollapsed</key>
+                                                                               <string>yes</string>
+                                                                               <key>sizes</key>
+                                                                               <array>
+                                                                                       <string>{{0, 0}, {308, 781}}</string>
+                                                                                       <string>{{308, 0}, {791, 781}}</string>
+                                                                               </array>
+                                                                       </dict>
+                                                               </dict>
+                                                               <key>LauncherConfigVersion</key>
+                                                               <string>8</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C162984064C10D400B95A72</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Debug - GLUTExamples (Underwater)</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>DebugConsoleVisible</key>
+                                                               <string>None</string>
+                                                               <key>DebugConsoleWindowFrame</key>
+                                                               <string>{{200, 200}, {500, 300}}</string>
+                                                               <key>DebugSTDIOWindowFrame</key>
+                                                               <string>{{200, 200}, {500, 300}}</string>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {1099, 781}}</string>
+                                                               <key>PBXDebugSessionStackFrameViewKey</key>
+                                                               <dict>
+                                                                       <key>DebugVariablesTableConfiguration</key>
+                                                                       <array>
+                                                                               <string>Name</string>
+                                                                               <real>120</real>
+                                                                               <string>Value</string>
+                                                                               <real>85</real>
+                                                                               <string>Summary</string>
+                                                                               <real>80</real>
+                                                                       </array>
+                                                                       <key>Frame</key>
+                                                                       <string>{{0, 302}, {308, 479}}</string>
+                                                                       <key>RubberWindowFrame</key>
+                                                                       <string>342 356 1099 822 0 0 1920 1178 </string>
+                                                               </dict>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>342 356 1099 822 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugSessionModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>781pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>781pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debugger</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugSessionModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1CD10A99069EF8BA00B06720</string>
+                               <string>022B4633121700F300A74F96</string>
+                               <string>1C162984064C10D400B95A72</string>
+                               <string>022B4634121700F300A74F96</string>
+                               <string>022B4635121700F300A74F96</string>
+                               <string>022B4636121700F300A74F96</string>
+                               <string>022B4637121700F300A74F96</string>
+                               <string>022B4638121700F300A74F96</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.debugV3</string>
+                       <key>WindowString</key>
+                       <string>342 356 1099 822 0 0 1920 1178 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1CD10A99069EF8BA00B06720</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.find</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Dock</key>
+                                                       <array>
+                                                               <dict>
+                                                                       <key>ContentConfiguration</key>
+                                                                       <dict>
+                                                                               <key>PBXProjectModuleGUID</key>
+                                                                               <string>1CDD528C0622207200134675</string>
+                                                                               <key>PBXProjectModuleLabel</key>
+                                                                               <string>Operation.cpp</string>
+                                                                               <key>StatusBarVisibility</key>
+                                                                               <true/>
+                                                                       </dict>
+                                                                       <key>GeometryConfiguration</key>
+                                                                       <dict>
+                                                                               <key>Frame</key>
+                                                                               <string>{{0, 0}, {792, 405}}</string>
+                                                                               <key>RubberWindowFrame</key>
+                                                                               <string>674 189 792 854 0 0 1920 1178 </string>
+                                                                       </dict>
+                                                                       <key>Module</key>
+                                                                       <string>PBXNavigatorGroup</string>
+                                                                       <key>Proportion</key>
+                                                                       <string>792pt</string>
+                                                               </dict>
+                                                       </array>
+                                                       <key>Proportion</key>
+                                                       <string>405pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD0528E0623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Project Find</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 410}, {792, 403}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>674 189 792 854 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXProjectFindModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>403pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>813pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project Find</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXProjectFindModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C530D57069F1CE1000CFCEE</string>
+                               <string>022B461B1216FE9C00A74F96</string>
+                               <string>022B461C1216FE9C00A74F96</string>
+                               <string>1CDD528C0622207200134675</string>
+                               <string>1CD0528E0623707200166675</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>674 189 792 854 0 0 1920 1178 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C530D57069F1CE1000CFCEE</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>MENUSEPARATOR</string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.debuggerConsole</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C78EAAC065D492600B07095</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Debugger Console</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {734, 603}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>998 534 734 644 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXDebugCLIModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>603pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>603pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debugger Console</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXDebugCLIModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C78EAAD065D492600B07095</string>
+                               <string>022B46821218654500A74F96</string>
+                               <string>1C78EAAC065D492600B07095</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.consoleV3</string>
+                       <key>WindowString</key>
+                       <string>998 534 734 644 0 0 1920 1178 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C78EAAD065D492600B07095</string>
+                       <key>WindowToolIsVisible</key>
+                       <true/>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.snapshots</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>XCSnapshotModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Snapshots</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCSnapshotModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <string>Yes</string>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.snapshots</string>
+                       <key>WindowString</key>
+                       <string>315 824 300 550 0 0 1440 878 </string>
+                       <key>WindowToolIsVisible</key>
+                       <string>Yes</string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.scm</string>
+                       <key>IsVertical</key>
+                       <true/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1C78EAB2065D492600B07095</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string></string>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {721, 0}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>1006 695 721 483 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>0pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXCVSModuleFilterTypeKey</key>
+                                                               <integer>1032</integer>
+                                                               <key>PBXCVSModuleTreeModuleColumnData</key>
+                                                               <dict>
+                                                                       <key>PBXCVSModuleTreeModuleColumnWidthsKey</key>
+                                                                       <array>
+                                                                               <real>305</real>
+                                                                               <real>56</real>
+                                                                               <real>63</real>
+                                                                               <real>60</real>
+                                                                               <real>63</real>
+                                                                               <real>139</real>
+                                                                       </array>
+                                                                       <key>PBXCVSModuleTreeModuleColumnsKey</key>
+                                                                       <array>
+                                                                               <string>Name</string>
+                                                                               <string>Status</string>
+                                                                               <string>Update</string>
+                                                                               <string>Revision</string>
+                                                                               <string>Author</string>
+                                                                               <string>Date</string>
+                                                                       </array>
+                                                               </dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CD052920623707200166675</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>SCM Results</string>
+                                                               <key>SCMActivityViewerShowingDefaultKey</key>
+                                                               <string>{{0, 304}, {721, 133}}</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 5}, {721, 437}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>1006 695 721 483 0 0 1920 1178 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXCVSModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>437pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>442pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>SCM</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXCVSModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>02D46D160FED80AF00E65706</string>
+                               <string>022B463B121700F300A74F96</string>
+                               <string>1C78EAB2065D492600B07095</string>
+                               <string>1CD052920623707200166675</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.scm</string>
+                       <key>WindowString</key>
+                       <string>1006 695 721 483 0 0 1920 1178 </string>
+                       <key>WindowToolGUID</key>
+                       <string>02D46D160FED80AF00E65706</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.breakpoints</string>
+                       <key>IsVertical</key>
+                       <false/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXBottomSmartGroupGIDs</key>
+                                                               <array>
+                                                                       <string>1C77FABC04509CD000000102</string>
+                                                               </array>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CE0B1FE06471DED0097A5F4</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Files</string>
+                                                               <key>PBXProjectStructureProvided</key>
+                                                               <string>no</string>
+                                                               <key>PBXSmartGroupTreeModuleColumnData</key>
+                                                               <dict>
+                                                                       <key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+                                                                       <array>
+                                                                               <real>168</real>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+                                                                       <array>
+                                                                               <string>MainColumn</string>
+                                                                       </array>
+                                                               </dict>
+                                                               <key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+                                                               <dict>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+                                                                       <array>
+                                                                               <string>1C77FABC04509CD000000102</string>
+                                                                               <string>1C3E0DCA080725EA00A55177</string>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+                                                                       <array>
+                                                                               <array>
+                                                                                       <integer>0</integer>
+                                                                               </array>
+                                                                       </array>
+                                                                       <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+                                                                       <string>{{0, 0}, {168, 350}}</string>
+                                                               </dict>
+                                                               <key>PBXTopSmartGroupGIDs</key>
+                                                               <array/>
+                                                               <key>XCIncludePerspectivesSwitch</key>
+                                                               <false/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {185, 368}}</string>
+                                                               <key>GroupTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>MainColumn</string>
+                                                                       <real>168</real>
+                                                               </array>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>28 375 744 409 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXSmartGroupTreeModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>185pt</string>
+                                               </dict>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CA1AED706398EBD00589147</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Detail</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{190, 0}, {554, 368}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>28 375 744 409 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCDetailModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>554pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>368pt</string>
+                               </dict>
+                       </array>
+                       <key>MajorVersion</key>
+                       <integer>3</integer>
+                       <key>MinorVersion</key>
+                       <integer>0</integer>
+                       <key>Name</key>
+                       <string>Breakpoints</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXSmartGroupTreeModule</string>
+                               <string>XCDetailModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>0258810E0CEE488000681C7E</string>
+                               <string>0258810F0CEE488000681C7E</string>
+                               <string>1CE0B1FE06471DED0097A5F4</string>
+                               <string>1CA1AED706398EBD00589147</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.breakpointsV3</string>
+                       <key>WindowString</key>
+                       <string>28 375 744 409 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>0258810E0CEE488000681C7E</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.debugAnimator</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>02E39A7909F721C80055992A</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string></string>
+                                                               <key>StatusBarVisibility</key>
+                                                               <true/>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {700, 459}}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>36 211 700 500 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXNavigatorGroup</string>
+                                                       <key>Proportion</key>
+                                                       <string>459pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>459pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Debug Visualizer</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXNavigatorGroup</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <true/>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.debugAnimatorV3</string>
+                       <key>WindowString</key>
+                       <string>36 211 700 500 0 0 1440 878 </string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.bookmarks</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>PBXBookmarksModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Bookmarks</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXBookmarksModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <false/>
+                       <key>WindowString</key>
+                       <string>538 42 401 187 0 0 1280 1002 </string>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.projectFormatConflicts</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>Module</key>
+                                                       <string>XCProjectFormatConflictsModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Project Format Conflicts</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCProjectFormatConflictsModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <false/>
+                       <key>WindowContentMinSize</key>
+                       <string>450 300</string>
+                       <key>WindowString</key>
+                       <string>50 850 472 307 0 0 1440 877</string>
+               </dict>
+               <dict>
+                       <key>FirstTimeWindowDisplayed</key>
+                       <false/>
+                       <key>Identifier</key>
+                       <string>windowTool.classBrowser</string>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>ContentConfiguration</key>
+                                                       <dict>
+                                                               <key>OptionsSetName</key>
+                                                               <string>Hierarchy, project classes</string>
+                                                               <key>PBXProjectModuleGUID</key>
+                                                               <string>1CA6456E063B45B4001379D8</string>
+                                                               <key>PBXProjectModuleLabel</key>
+                                                               <string>Class Browser - RijndaelCBCMAC</string>
+                                                       </dict>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>ClassesFrame</key>
+                                                               <string>{{0, 0}, {759, 298}}</string>
+                                                               <key>ClassesTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>PBXClassNameColumnIdentifier</string>
+                                                                       <real>208</real>
+                                                                       <string>PBXClassBookColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                               </array>
+                                                               <key>Frame</key>
+                                                               <string>{{0, 0}, {1011, 802}}</string>
+                                                               <key>MembersFrame</key>
+                                                               <string>{{0, 303}, {759, 499}}</string>
+                                                               <key>MembersTreeTableConfiguration</key>
+                                                               <array>
+                                                                       <string>PBXMemberTypeIconColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                                       <string>PBXMemberNameColumnIdentifier</string>
+                                                                       <real>216</real>
+                                                                       <string>PBXMemberTypeColumnIdentifier</string>
+                                                                       <real>482</real>
+                                                                       <string>PBXMemberBookColumnIdentifier</string>
+                                                                       <real>22</real>
+                                                               </array>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>159 56 1011 822 0 0 1440 878 </string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>PBXClassBrowserModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>802pt</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>802pt</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Class Browser</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>PBXClassBrowserModule</string>
+                       </array>
+                       <key>StatusbarIsVisible</key>
+                       <false/>
+                       <key>TableOfContents</key>
+                       <array>
+                               <string>1C0AD2AF069F1E9B00FABCE6</string>
+                               <string>1C0AD2B0069F1E9B00FABCE6</string>
+                               <string>1CA6456E063B45B4001379D8</string>
+                       </array>
+                       <key>ToolbarConfiguration</key>
+                       <string>xcode.toolbar.config.classbrowser</string>
+                       <key>WindowString</key>
+                       <string>159 56 1011 822 0 0 1440 878 </string>
+                       <key>WindowToolGUID</key>
+                       <string>1C0AD2AF069F1E9B00FABCE6</string>
+                       <key>WindowToolIsVisible</key>
+                       <false/>
+               </dict>
+               <dict>
+                       <key>Identifier</key>
+                       <string>windowTool.refactoring</string>
+                       <key>IncludeInToolsMenu</key>
+                       <false/>
+                       <key>Layout</key>
+                       <array>
+                               <dict>
+                                       <key>Dock</key>
+                                       <array>
+                                               <dict>
+                                                       <key>BecomeActive</key>
+                                                       <true/>
+                                                       <key>GeometryConfiguration</key>
+                                                       <dict>
+                                                               <key>Frame</key>
+                                                               <string>{0, 0}, {500, 335}</string>
+                                                               <key>RubberWindowFrame</key>
+                                                               <string>{0, 0}, {500, 335}</string>
+                                                       </dict>
+                                                       <key>Module</key>
+                                                       <string>XCRefactoringModule</string>
+                                                       <key>Proportion</key>
+                                                       <string>100%</string>
+                                               </dict>
+                                       </array>
+                                       <key>Proportion</key>
+                                       <string>100%</string>
+                               </dict>
+                       </array>
+                       <key>Name</key>
+                       <string>Refactoring</string>
+                       <key>ServiceClasses</key>
+                       <array>
+                               <string>XCRefactoringModule</string>
+                       </array>
+                       <key>WindowString</key>
+                       <string>200 200 500 356 0 0 1920 1200 </string>
+               </dict>
+       </array>
+</dict>
+</plist>
diff --git a/tools/elftosb/elftosb.xcodeproj/creed.pbxuser b/tools/elftosb/elftosb.xcodeproj/creed.pbxuser
new file mode 100644 (file)
index 0000000..b2b2767
--- /dev/null
@@ -0,0 +1,4452 @@
+// !$*UTF8*$!
+{
+       0208BEB10A02D2B800255D31 /* SHA1.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 3556}}";
+                       sepNavSelRange = "{4579, 54}";
+                       sepNavVisRange = "{3781, 1473}";
+                       sepNavVisRect = "{{0, 1086}, {736, 782}}";
+               };
+       };
+       0208BEB20A02D2B800255D31 /* SHA1.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {811, 2100}}";
+                       sepNavSelRange = "{2747, 12}";
+                       sepNavVisRect = "{{0, 1319}, {811, 482}}";
+               };
+       };
+       0208BF4A0A03137800255D31 /* Random.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 924}}";
+                       sepNavSelRange = "{1299, 0}";
+                       sepNavVisRange = "{201, 1260}";
+                       sepNavVisRect = "{{0, 142}, {706, 782}}";
+               };
+       };
+       0208BF4B0A03137800255D31 /* Random.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {745, 1316}}";
+                       sepNavSelRange = "{1172, 5}";
+                       sepNavVisRect = "{{0, 583}, {745, 388}}";
+               };
+       };
+       0208BF890A03E04800255D31 /* RijndaelCBCMAC.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {811, 994}}";
+                       sepNavSelRange = "{713, 21}";
+                       sepNavVisRect = "{{0, 512}, {811, 482}}";
+               };
+       };
+       0208BF8A0A03E04800255D31 /* RijndaelCBCMAC.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {745, 1330}}";
+                       sepNavSelRange = "{2069, 0}";
+                       sepNavVisRect = "{{0, 611}, {745, 388}}";
+               };
+       };
+       0208C03D0A0544BA00255D31 /* options.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {736, 15974}}";
+                       sepNavSelRange = "{28198, 63}";
+                       sepNavVisRect = "{{0, 13343}, {736, 782}}";
+               };
+       };
+       0208C03E0A0544BA00255D31 /* options.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {811, 6846}}";
+                       sepNavSelRange = "{4732, 40}";
+                       sepNavVisRect = "{{0, 2202}, {811, 482}}";
+               };
+       };
+       0208C08B0A05677000255D31 /* AESKey.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1218}}";
+                       sepNavSelRange = "{968, 0}";
+                       sepNavVisRange = "{280, 1825}";
+                       sepNavVisRect = "{{0, 266}, {706, 782}}";
+               };
+       };
+       0208C2880A0A4E5F00255D31 /* DataSource.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 3094}}";
+                       sepNavSelRange = "{2183, 48}";
+                       sepNavVisRange = "{30, 2207}";
+                       sepNavVisRect = "{{0, 280}, {706, 782}}";
+               };
+       };
+       0208C2890A0A4E5F00255D31 /* DataSource.h */ = {
+               uiCtxt = {
+                       sepNavFolds = "{\n    c =     (\n                {\n            r = \"{3114, 1494}\";\n            s = 0;\n        }\n    );\n    r = \"{0, 9539}\";\n    s = 0;\n}";
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 3406}}";
+                       sepNavSelRange = "{3191, 0}";
+                       sepNavVisRange = "{1297, 2673}";
+                       sepNavVisRect = "{{0, 1254}, {706, 782}}";
+               };
+       };
+       0208C28A0A0A4E5F00255D31 /* Operation.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {731, 936}}";
+                       sepNavSelRange = "{753, 9}";
+                       sepNavVisRange = "{430, 602}";
+                       sepNavVisRect = "{{0, 30}, {706, 782}}";
+               };
+       };
+       0208C28B0A0A4E5F00255D31 /* Operation.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 2674}}";
+                       sepNavSelRange = "{1618, 0}";
+                       sepNavVisRange = "{1197, 1240}";
+                       sepNavVisRect = "{{0, 759}, {732, 782}}";
+               };
+       };
+       0208C28C0A0A4E5F00255D31 /* DataTarget.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 1076}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{0, 2068}";
+                       sepNavVisRect = "{{0, 564}, {745, 388}}";
+               };
+       };
+       0208C28D0A0A4E5F00255D31 /* DataTarget.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 1703}}";
+                       sepNavSelRange = "{2252, 0}";
+                       sepNavVisRange = "{931, 2954}";
+                       sepNavVisRect = "{{0, 406}, {706, 782}}";
+               };
+       };
+       0208C2990A0A4EE800255D31 /* ConversionController.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 18707}}";
+                       sepNavSelRange = "{36256, 0}";
+                       sepNavVisRange = "{35162, 2941}";
+                       sepNavVisRect = "{{0, 7204}, {706, 782}}";
+                       sepNavWindowFrame = "{{15, -5}, {777, 878}}";
+               };
+       };
+       0208C29A0A0A4EE800255D31 /* ConversionController.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 2223}}";
+                       sepNavSelRange = "{4632, 0}";
+                       sepNavVisRange = "{1812, 2982}";
+                       sepNavVisRect = "{{0, 1402}, {706, 782}}";
+               };
+       };
+       0208C2E00A0AA4F700255D31 /* int_size.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 778}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{0, 751}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       020D416A0A0FE8AC0027E24E /* StringMatcher.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 994}}";
+                       sepNavSelRange = "{1117, 0}";
+                       sepNavVisRect = "{{0, 212}, {706, 782}}";
+               };
+       };
+       020D41850A0FF0C20027E24E /* OutputSection.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 1134}}";
+                       sepNavSelRange = "{625, 0}";
+                       sepNavVisRect = "{{0, 336}, {706, 782}}";
+               };
+       };
+       020D41860A0FF0C20027E24E /* OutputSection.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 782}}";
+                       sepNavSelRange = "{29, 0}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       020D41970A0FF5BF0027E24E /* BootImageGenerator.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1092}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{481, 1843}";
+                       sepNavVisRect = "{{0, 140}, {706, 782}}";
+               };
+       };
+       020D41980A0FF5BF0027E24E /* BootImageGenerator.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1148}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{202, 1426}";
+                       sepNavVisRect = "{{0, 351}, {706, 782}}";
+               };
+       };
+       020D41A30A0FF8880027E24E /* Version.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 840}}";
+                       sepNavSelRange = "{627, 17}";
+                       sepNavVisRange = "{78, 1276}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       020D41A40A0FF8880027E24E /* Version.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {736, 1820}}";
+                       sepNavSelRange = "{833, 0}";
+                       sepNavVisRect = "{{0, 56}, {736, 782}}";
+               };
+       };
+       020D41AE0A0FFB040027E24E /* BootImage.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 882}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{83, 1600}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       020D41B70A0FFD140027E24E /* EncoreBootImageGenerator.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {740, 1076}}";
+                       sepNavSelRange = "{918, 0}";
+                       sepNavVisRange = "{0, 2176}";
+                       sepNavVisRect = "{{0, 233}, {706, 542}}";
+                       sepNavWindowFrame = "{{15, -5}, {777, 878}}";
+               };
+       };
+       020D41B80A0FFD140027E24E /* EncoreBootImageGenerator.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 3991}}";
+                       sepNavSelRange = "{5399, 0}";
+                       sepNavVisRange = "{4738, 2409}";
+                       sepNavVisRect = "{{0, 2571}, {706, 782}}";
+               };
+       };
+       020D43A50A14D7E20027E24E /* Logging.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {811, 3276}}";
+                       sepNavSelRange = "{6107, 22}";
+                       sepNavVisRect = "{{0, 2286}, {811, 482}}";
+               };
+       };
+       020D43A60A14D7E20027E24E /* Logging.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {736, 1400}}";
+                       sepNavSelRange = "{1208, 0}";
+                       sepNavVisRect = "{{0, 618}, {736, 782}}";
+               };
+       };
+       020D45040A1523350027E24E /* GHSSecInfo.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1148}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{665, 1793}";
+                       sepNavVisRect = "{{0, 268}, {736, 782}}";
+               };
+       };
+       020D45050A1523350027E24E /* GHSSecInfo.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 1540}}";
+                       sepNavSelRange = "{2485, 0}";
+                       sepNavVisRect = "{{0, 114}, {706, 782}}";
+               };
+       };
+       020D454F0A1533550027E24E /* OptionContext.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 826}}";
+                       sepNavSelRange = "{1259, 0}";
+                       sepNavVisRect = "{{0, 28}, {732, 782}}";
+               };
+       };
+       020D467A0A16657C0027E24E /* sbtool */ = {
+               activeExec = 0;
+               executables = (
+                       020D467C0A16657C0027E24E /* sbtool */,
+               );
+       };
+       020D467C0A16657C0027E24E /* sbtool */ = {
+               isa = PBXExecutable;
+               activeArgIndices = (
+                       NO,
+                       NO,
+                       YES,
+                       YES,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       YES,
+                       NO,
+               );
+               argumentStrings = (
+                       "--quiet",
+                       "--debug",
+                       "--verbose",
+                       "-z",
+                       "-k",
+                       test1.key,
+                       "--zero-key",
+                       "--extract",
+                       0,
+                       1,
+                       3,
+                       5,
+                       8,
+                       "--binary",
+                       test_output/output.sb2,
+                       nand_profile_bd/nand_profile.sb,
+               );
+               autoAttachOnCrash = 1;
+               breakpointsEnabled = 0;
+               configStateDict = {
+                       "PBXLSLaunchAction-0" = {
+                               PBXLSLaunchAction = 0;
+                               PBXLSLaunchStartAction = 1;
+                               PBXLSLaunchStdioStyle = 2;
+                               PBXLSLaunchStyle = 0;
+                               class = PBXLSRunLaunchConfig;
+                               displayName = "Executable Runner";
+                               identifier = com.apple.Xcode.launch.runConfig;
+                               remoteHostInfo = "";
+                               startActionInfo = "";
+                       };
+               };
+               customDataFormattersEnabled = 1;
+               dataTipCustomDataFormattersEnabled = 1;
+               dataTipShowTypeColumn = 1;
+               dataTipSortType = 0;
+               debuggerPlugin = GDBDebugging;
+               disassemblyDisplayState = 0;
+               dylibVariantSuffix = "";
+               enableDebugStr = 1;
+               environmentEntries = (
+               );
+               executableSystemSymbolLevel = 0;
+               executableUserSymbolLevel = 0;
+               libgmallocEnabled = 0;
+               name = sbtool;
+               savedGlobals = {
+               };
+               showTypeColumn = 0;
+               sourceDirectories = (
+               );
+               startupPath = "<<ProjectDirectory>>";
+               variableFormatDictionary = {
+               };
+       };
+       020D46830A1665D90027E24E /* sbtool.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 8960}}";
+                       sepNavSelRange = "{844, 0}";
+                       sepNavVisRange = "{23, 1414}";
+                       sepNavVisRect = "{{0, 6036}, {706, 782}}";
+               };
+       };
+       020D47A00A16C1E00027E24E /* EncoreBootImageReader.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1764}}";
+                       sepNavSelRange = "{863, 0}";
+                       sepNavVisRange = "{682, 1721}";
+                       sepNavVisRect = "{{0, 922}, {706, 782}}";
+               };
+       };
+       020D47A10A16C1E00027E24E /* EncoreBootImageReader.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 5096}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{3994, 2023}";
+                       sepNavVisRect = "{{0, 219}, {706, 782}}";
+               };
+       };
+       020DDBEA0A1D08AD00E1CB49 /* OptionDictionary.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 1288}}";
+                       sepNavSelRange = "{1197, 16}";
+                       sepNavVisRect = "{{0, 460}, {732, 782}}";
+               };
+       };
+       020DDBEB0A1D08AD00E1CB49 /* OptionDictionary.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 1582}}";
+                       sepNavSelRange = "{2894, 0}";
+                       sepNavVisRect = "{{0, 556}, {732, 782}}";
+               };
+       };
+       020DDCA30A1E32A400E1CB49 /* PBXCPPExceptionBreakpoint */ = {
+               isa = PBXCPPExceptionBreakpoint;
+               actions = (
+               );
+               breakpointStyle = 0;
+               condition = 020DDCA50A1E32C200E1CB49 /* XCCPPCondition */;
+               continueAfterActions = 0;
+               countType = 0;
+               delayBeforeContinue = 0;
+               exceptionName = $;
+               hitCount = 0;
+               ignoreCount = 0;
+               isThrow = 0;
+               modificationTime = 267302557.457919;
+               originalNumberOfMultipleMatches = 0;
+               state = 2;
+       };
+       020DDCA50A1E32C200E1CB49 /* XCCPPCondition */ = {
+               isa = XCCPPCondition;
+               conditionString = "On Catch";
+       };
+       020DDCE80A1E858600E1CB49 /* Everything */ = {
+               activeExec = 0;
+       };
+       02123F2F0A6B057E003CF33F /* Blob.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {740, 1076}}";
+                       sepNavSelRange = "{1584, 0}";
+                       sepNavVisRange = "{0, 1876}";
+                       sepNavVisRect = "{{0, 296}, {706, 782}}";
+               };
+       };
+       02123F300A6B057E003CF33F /* Blob.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 1547}}";
+                       sepNavSelRange = "{1143, 4}";
+                       sepNavVisRange = "{0, 1990}";
+                       sepNavVisRect = "{{0, 215}, {706, 782}}";
+               };
+       };
+       02123F370A6B09CF003CF33F /* HexValues.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 779}}";
+                       sepNavSelRange = "{471, 0}";
+                       sepNavVisRange = "{0, 872}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       02123F380A6B09CF003CF33F /* HexValues.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 782}}";
+                       sepNavSelRange = "{1007, 0}";
+                       sepNavVisRect = "{{0, 0}, {732, 782}}";
+               };
+       };
+       0215B3BA09F3FBF100EA7C45 /* ElftosbLexer.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {683, 1443}}";
+                       sepNavSelRange = "{742, 34}";
+                       sepNavVisRange = "{694, 198}";
+                       sepNavVisRect = "{{0, 266}, {732, 782}}";
+                       sepNavWindowFrame = "{{15, 63}, {775, 810}}";
+               };
+       };
+       0215B3D209F424D800EA7C45 /* elftosb_parser.y */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 13351}}";
+                       sepNavSelRange = "{11226, 0}";
+                       sepNavVisRange = "{10479, 1812}";
+                       sepNavVisRect = "{{0, 11622}, {706, 782}}";
+               };
+       };
+       021CA3F00A8D16960028326F /* ExcludesListMatcher.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1064}}";
+                       sepNavSelRange = "{1122, 0}";
+                       sepNavVisRange = "{596, 1642}";
+                       sepNavVisRect = "{{0, 218}, {706, 782}}";
+               };
+       };
+       021CA3F10A8D16960028326F /* ExcludesListMatcher.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1358}}";
+                       sepNavSelRange = "{2115, 0}";
+                       sepNavVisRange = "{1018, 1218}";
+                       sepNavVisRect = "{{0, 0}, {732, 782}}";
+               };
+       };
+       021CA4400A8D2F740028326F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020DDBEA0A1D08AD00E1CB49 /* OptionDictionary.h */;
+               name = OptionDictionary;
+               rLen = 16;
+               rLoc = 1197;
+               rType = 0;
+               vrLen = 1754;
+               vrLoc = 1102;
+       };
+       021CA4420A8D2F740028326F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020DDBEB0A1D08AD00E1CB49 /* OptionDictionary.cpp */;
+               name = "OptionDictionary.cpp: 107";
+               rLen = 0;
+               rLoc = 2894;
+               rType = 0;
+               vrLen = 1547;
+               vrLoc = 1144;
+       };
+       022B461212136A6A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535B40C245AEC00CBD4A5 /* DataSourceImager.cpp */;
+               name = "DataSourceImager.cpp: 17";
+               rLen = 0;
+               rLoc = 528;
+               rType = 0;
+               vrLen = 278;
+               vrLoc = 360;
+       };
+       022B461312136A6A00A74F96 /* XCBuildMessageTextBookmark */ = {
+               isa = PBXTextBookmark;
+               comments = "Malloc.h: No such file or directory";
+               fRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */;
+               fallbackIsa = XCBuildMessageTextBookmark;
+               rLen = 1;
+               rLoc = 20;
+               rType = 1;
+       };
+       022B461412136A6A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */;
+               name = "format_string.cpp: 21";
+               rLen = 0;
+               rLoc = 602;
+               rType = 0;
+               vrLen = 290;
+               vrLoc = 478;
+       };
+       022B46161216FE9C00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */;
+               name = "format_string.cpp: 21";
+               rLen = 0;
+               rLoc = 602;
+               rType = 0;
+               vrLen = 290;
+               vrLoc = 478;
+       };
+       022B46181216FE9C00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 704";
+               rLen = 9;
+               rLoc = 21541;
+               rType = 0;
+               vrLen = 651;
+               vrLoc = 21067;
+       };
+       022B46191216FE9C00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+       };
+       022B461A1216FE9C00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B461D1216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02123F300A6B057E003CF33F /* Blob.cpp */;
+               name = "Blob.cpp: 52";
+               rLen = 4;
+               rLoc = 1143;
+               rType = 0;
+               vrLen = 1990;
+               vrLoc = 0;
+       };
+       022B461E1216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0296A49309D9AE9400F80AFF /* elftosb.cpp */;
+               name = "elftosb.cpp: 45";
+               rLen = 0;
+               rLoc = 1198;
+               rType = 0;
+               vrLen = 2223;
+               vrLoc = 13685;
+       };
+       022B461F1216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535B30C245AEC00CBD4A5 /* DataSourceImager.h */;
+               name = "DataSourceImager.h: 55";
+               rLen = 0;
+               rLoc = 1268;
+               rType = 0;
+               vrLen = 1359;
+               vrLoc = 0;
+       };
+       022B46201216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28C0A0A4E5F00255D31 /* DataTarget.cpp */;
+               name = "DataTarget.cpp: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 2068;
+               vrLoc = 0;
+       };
+       022B46211216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2890A0A4E5F00255D31 /* DataSource.h */;
+               name = "DataSource.h: 151";
+               rLen = 9;
+               rLoc = 4826;
+               rType = 0;
+               vrLen = 2727;
+               vrLoc = 2520;
+       };
+       022B46221216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 704";
+               rLen = 9;
+               rLoc = 21541;
+               rType = 0;
+               vrLen = 2033;
+               vrLoc = 20377;
+       };
+       022B46231216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28D0A0A4E5F00255D31 /* DataTarget.h */;
+               name = "DataTarget.h: 72";
+               rLen = 0;
+               rLoc = 2252;
+               rType = 0;
+               vrLen = 2954;
+               vrLoc = 931;
+       };
+       022B46241216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41B80A0FFD140027E24E /* EncoreBootImageGenerator.cpp */;
+               name = "EncoreBootImageGenerator.cpp: 195";
+               rLen = 0;
+               rLoc = 5404;
+               rType = 0;
+               vrLen = 2422;
+               vrLoc = 4738;
+       };
+       022B46251216FEA700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41B80A0FFD140027E24E /* EncoreBootImageGenerator.cpp */;
+               name = "EncoreBootImageGenerator.cpp: 194";
+               rLen = 0;
+               rLoc = 5399;
+               rType = 0;
+               vrLen = 2409;
+               vrLoc = 4738;
+       };
+       022B4632121700F300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */;
+               name = "format_string.cpp: 21";
+               rLen = 0;
+               rLoc = 602;
+               rType = 0;
+               vrLen = 290;
+               vrLoc = 478;
+       };
+       022B4639121700F300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B464E1217576E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */;
+               name = "format_string.cpp: 21";
+               rLen = 0;
+               rLoc = 602;
+               rType = 0;
+               vrLen = 290;
+               vrLoc = 478;
+       };
+       022B464F1217576E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 15";
+               rLen = 26;
+               rLoc = 189;
+               rType = 0;
+               vrLen = 233;
+               vrLoc = 125;
+       };
+       022B46501217576E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02D46C110FED492400E65706 /* elftosb_parser.tab.cpp */;
+               name = "elftosb_parser.tab.cpp: 141";
+               rLen = 0;
+               rLoc = 3846;
+               rType = 0;
+               vrLen = 297;
+               vrLoc = 3210;
+       };
+       022B46511217576E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3BA09F3FBF100EA7C45 /* ElftosbLexer.h */;
+               name = "ElftosbLexer.h: 24";
+               rLen = 34;
+               rLoc = 742;
+               rType = 0;
+               vrLen = 198;
+               vrLoc = 694;
+       };
+       022B46521217576E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 380;
+               vrLoc = 1267;
+       };
+       022B46531217576E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 380;
+               vrLoc = 1267;
+       };
+       022B46541217576E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B4655121763A100A74F96 /* IVTDataSource.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {683, 3887}}";
+                       sepNavSelRange = "{9792, 0}";
+                       sepNavVisRange = "{9594, 261}";
+               };
+       };
+       022B4656121763A100A74F96 /* IVTDataSource.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 1365}}";
+                       sepNavSelRange = "{569, 0}";
+                       sepNavVisRange = "{519, 1989}";
+               };
+       };
+       022B46601218557900A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 380;
+               vrLoc = 1267;
+       };
+       022B46611218557900A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B466412185DA400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 380;
+               vrLoc = 1267;
+       };
+       022B466512185DA400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B466C12185F4800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 380;
+               vrLoc = 1267;
+       };
+       022B466D12185F4800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46701218625A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 380;
+               vrLoc = 1267;
+       };
+       022B46711218625A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B4678121864A000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 380;
+               vrLoc = 1267;
+       };
+       022B4679121864A000A74F96 /* XCBuildMessageTextBookmark */ = {
+               isa = PBXTextBookmark;
+               comments = "Field 'm_ivt' has incomplete type";
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               fallbackIsa = XCBuildMessageTextBookmark;
+               rLen = 1;
+               rLoc = 282;
+               rType = 1;
+       };
+       022B467A121864A000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B467B121864A000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46801218654500A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46811218654500A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46871218659100A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46881218659100A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46891218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 916";
+               rLen = 0;
+               rLoc = 21776;
+               rType = 0;
+               vrLen = 1970;
+               vrLoc = 20175;
+       };
+       022B468A1218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 2085;
+               vrLoc = 0;
+       };
+       022B468B1218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C29A0A0A4EE800255D31 /* ConversionController.h */;
+               name = "ConversionController.h: 128";
+               rLen = 0;
+               rLoc = 4632;
+               rType = 0;
+               vrLen = 2982;
+               vrLoc = 1812;
+       };
+       022B468C1218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157309F543FE00ABE650 /* ElftosbAST.h */;
+               name = "ElftosbAST.h: 619";
+               rLen = 0;
+               rLoc = 16098;
+               rType = 0;
+               vrLen = 2151;
+               vrLoc = 15487;
+       };
+       022B468D1218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2880A0A4E5F00255D31 /* DataSource.cpp */;
+               name = "DataSource.cpp: 83";
+               rLen = 48;
+               rLoc = 2183;
+               rType = 0;
+               vrLen = 2207;
+               vrLoc = 30;
+       };
+       022B468E1218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2890A0A4E5F00255D31 /* DataSource.h */;
+               name = "DataSource.h: 143";
+               rLen = 0;
+               rLoc = 4684;
+               rType = 0;
+               vrLen = 4166;
+               vrLoc = 1297;
+       };
+       022B468F1218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535B40C245AEC00CBD4A5 /* DataSourceImager.cpp */;
+               name = "DataSourceImager.cpp: 17";
+               rLen = 40;
+               rLoc = 512;
+               rType = 0;
+               vrLen = 2065;
+               vrLoc = 482;
+       };
+       022B46901218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41B80A0FFD140027E24E /* EncoreBootImageGenerator.cpp */;
+               name = "EncoreBootImageGenerator.cpp: 194";
+               rLen = 0;
+               rLoc = 5399;
+               rType = 0;
+               vrLen = 2409;
+               vrLoc = 4738;
+       };
+       022B46911218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 539";
+               rLen = 0;
+               rLoc = 13192;
+               rType = 0;
+               vrLen = 2003;
+               vrLoc = 12514;
+       };
+       022B46921218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28C0A0A4E5F00255D31 /* DataTarget.cpp */;
+               name = "DataTarget.cpp: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 2068;
+               vrLoc = 0;
+       };
+       022B46931218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28D0A0A4E5F00255D31 /* DataTarget.h */;
+               name = "DataTarget.h: 72";
+               rLen = 0;
+               rLoc = 2252;
+               rType = 0;
+               vrLen = 2954;
+               vrLoc = 931;
+       };
+       022B46941218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4656121763A100A74F96 /* IVTDataSource.cpp */;
+               name = "IVTDataSource.cpp: 17";
+               rLen = 0;
+               rLoc = 569;
+               rType = 0;
+               vrLen = 1989;
+               vrLoc = 519;
+       };
+       022B46951218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 278";
+               rLen = 0;
+               rLoc = 9736;
+               rType = 0;
+               vrLen = 2953;
+               vrLoc = 1371;
+       };
+       022B46961218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1201";
+               rLen = 0;
+               rLoc = 36267;
+               rType = 0;
+               vrLen = 2895;
+               vrLoc = 35162;
+       };
+       022B46971218659A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1201";
+               rLen = 0;
+               rLoc = 36267;
+               rType = 0;
+               vrLen = 2893;
+               vrLoc = 35162;
+       };
+       022B469D121865E000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 248;
+               vrLoc = 9594;
+       };
+       022B469E121865E000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 580;
+               vrLoc = 430;
+       };
+       022B46A1121865E300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46A2121865E300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46A5121865F700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46A6121865F700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46A91218660A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46AA1218660A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46AD1218662100A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46AE1218662100A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46B11218662D00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46B21218662D00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46B31218663500A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1201";
+               rLen = 0;
+               rLoc = 36267;
+               rType = 0;
+               vrLen = 2893;
+               vrLoc = 35162;
+       };
+       022B46B71218665300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46B81218665300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46B91218665600A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1201";
+               rLen = 0;
+               rLoc = 36267;
+               rType = 0;
+               vrLen = 2893;
+               vrLoc = 35162;
+       };
+       022B46BD1218667B00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46BE1218667B00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46C11218673300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46C21218673300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46C3121867D800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1201";
+               rLen = 0;
+               rLoc = 36267;
+               rType = 0;
+               vrLen = 2895;
+               vrLoc = 35162;
+       };
+       022B46C61218685B00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46C71218685B00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46C81218686300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1201";
+               rLen = 0;
+               rLoc = 36267;
+               rType = 0;
+               vrLen = 2893;
+               vrLoc = 35162;
+       };
+       022B46CC1218687300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46CD1218687300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46CE1218687700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1201";
+               rLen = 0;
+               rLoc = 36267;
+               rType = 0;
+               vrLen = 2895;
+               vrLoc = 35162;
+       };
+       022B46D1121868F200A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46D2121868F200A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46D3121868FD00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1162";
+               rLen = 0;
+               rLoc = 35162;
+               rType = 0;
+               vrLen = 2895;
+               vrLoc = 35162;
+       };
+       022B46D4121868FD00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 539";
+               rLen = 0;
+               rLoc = 13192;
+               rType = 0;
+               vrLen = 2003;
+               vrLoc = 12514;
+       };
+       022B46D5121868FD00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 216";
+               rLen = 0;
+               rLoc = 5696;
+               rType = 0;
+               vrLen = 1993;
+               vrLoc = 4162;
+       };
+       022B46D81218690400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46D91218690400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46DC1218694400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46DD1218694400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46DE1218694900A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 216";
+               rLen = 0;
+               rLoc = 5696;
+               rType = 0;
+               vrLen = 1993;
+               vrLoc = 4162;
+       };
+       022B46E11218696F00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46E21218696F00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46E31218697600A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 216";
+               rLen = 0;
+               rLoc = 5696;
+               rType = 0;
+               vrLen = 1993;
+               vrLoc = 4162;
+       };
+       022B46E61218699C00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46E71218699C00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46E8121869A100A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 216";
+               rLen = 0;
+               rLoc = 5696;
+               rType = 0;
+               vrLen = 1985;
+               vrLoc = 4162;
+       };
+       022B46EC12186A4400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46ED12186A4400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46EE12186A5B00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 216";
+               rLen = 0;
+               rLoc = 5696;
+               rType = 0;
+               vrLen = 1993;
+               vrLoc = 4162;
+       };
+       022B46F112186A6700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46F212186A6700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46F312186A8300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 216";
+               rLen = 0;
+               rLoc = 5696;
+               rType = 0;
+               vrLen = 1993;
+               vrLoc = 4162;
+       };
+       022B46F612186AFC00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46F712186AFC00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46FA1218B7B300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46FB1218B7B300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B46FE1218B7F600A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B46FF1218B7F600A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47021218B95800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B47031218B95800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47041218B95D00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 154";
+               rLen = 0;
+               rLoc = 4145;
+               rType = 0;
+               vrLen = 1864;
+               vrLoc = 12242;
+       };
+       022B47051218B95D00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1162";
+               rLen = 0;
+               rLoc = 35162;
+               rType = 0;
+               vrLen = 2895;
+               vrLoc = 35162;
+       };
+       022B47061218B95D00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1195";
+               rLen = 0;
+               rLoc = 36256;
+               rType = 0;
+               vrLen = 2941;
+               vrLoc = 35162;
+       };
+       022B47091218B96300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B470A1218B96300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B470D1218B99F00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B470E1218B99F00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B470F1218B9AF00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1195";
+               rLen = 0;
+               rLoc = 36256;
+               rType = 0;
+               vrLen = 2941;
+               vrLoc = 35162;
+       };
+       022B47121218B9B300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B47131218B9B300A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47161218C00000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B47171218C00000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47181218C00400A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1195";
+               rLen = 0;
+               rLoc = 36256;
+               rType = 0;
+               vrLen = 2941;
+               vrLoc = 35162;
+       };
+       022B471B1218C00E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B471C1218C00E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B471D1218C01000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1195";
+               rLen = 0;
+               rLoc = 36256;
+               rType = 0;
+               vrLen = 2941;
+               vrLoc = 35162;
+       };
+       022B47201218C12800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B47211218C12800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47221218C13000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1195";
+               rLen = 0;
+               rLoc = 36256;
+               rType = 0;
+               vrLen = 2911;
+               vrLoc = 35162;
+       };
+       022B47261218C17D00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B47271218C17D00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47281218C17F00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 1195";
+               rLen = 0;
+               rLoc = 36256;
+               rType = 0;
+               vrLen = 2941;
+               vrLoc = 35162;
+       };
+       022B47291218C17F00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 154";
+               rLen = 0;
+               rLoc = 4145;
+               rType = 0;
+               vrLen = 2564;
+               vrLoc = 2608;
+       };
+       022B472A1218C17F00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 809";
+               rLen = 0;
+               rLoc = 20588;
+               rType = 0;
+               vrLen = 2382;
+               vrLoc = 18475;
+       };
+       022B472D1218C18600A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B472E1218C18600A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B472F1218C19000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 809";
+               rLen = 0;
+               rLoc = 20588;
+               rType = 0;
+               vrLen = 2353;
+               vrLoc = 18475;
+       };
+       022B47351218C46700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 022B4655121763A100A74F96 /* IVTDataSource.h */;
+               name = "IVTDataSource.h: 283";
+               rLen = 0;
+               rLoc = 9792;
+               rType = 0;
+               vrLen = 261;
+               vrLoc = 9594;
+       };
+       022B47361218C46700A74F96 /* XCBuildMessageTextBookmark */ = {
+               isa = PBXTextBookmark;
+               comments = "Expected primary-expression before '(' token";
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               fallbackIsa = XCBuildMessageTextBookmark;
+               rLen = 1;
+               rLoc = 332;
+               rType = 1;
+       };
+       022B47371218C46700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B47381218C46700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47391218C46A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02F8D5600A0152AB004CBE69 /* SourceFile.h */;
+               name = "SourceFile.h: 110";
+               rLen = 20;
+               rLoc = 3395;
+               rType = 0;
+               vrLen = 2643;
+               vrLoc = 1842;
+       };
+       022B473A1218C46A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157309F543FE00ABE650 /* ElftosbAST.h */;
+               name = "ElftosbAST.h: 1118";
+               rLen = 13;
+               rLoc = 29207;
+               rType = 0;
+               vrLen = 2093;
+               vrLoc = 28110;
+       };
+       022B473B1218C46A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 813";
+               rLen = 0;
+               rLoc = 20588;
+               rType = 0;
+               vrLen = 2224;
+               vrLoc = 19102;
+       };
+       022B473C1218C46A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7333;
+               rType = 0;
+               vrLen = 2018;
+               vrLoc = 6493;
+       };
+       022B473F1218C46E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B47401218C46E00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47411218C47C00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7333;
+               rType = 0;
+               vrLen = 2016;
+               vrLoc = 6493;
+       };
+       022B47451218C49900A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B47461218C49900A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47491218CA9900A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B474A1218CA9900A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B474B1218CA9A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7333;
+               rType = 0;
+               vrLen = 2018;
+               vrLoc = 6493;
+       };
+       022B474C1218CA9A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 61";
+               rLen = 0;
+               rLoc = 1417;
+               rType = 0;
+               vrLen = 1528;
+               vrLoc = 3894;
+       };
+       022B474D1218CA9A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 809";
+               rLen = 0;
+               rLoc = 20588;
+               rType = 0;
+               vrLen = 2224;
+               vrLoc = 19102;
+       };
+       022B474E1218CA9A00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 2169;
+               vrLoc = 19508;
+       };
+       022B47511218CAA200A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B47521218CAA200A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47531218CAAA00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 2130;
+               vrLoc = 19547;
+       };
+       022B47571218CACE00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B47581218CACE00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B475B1218CAD200A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B475C1218CAD200A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B475D1218CAD700A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 454";
+               rLen = 0;
+               rLoc = 11226;
+               rType = 0;
+               vrLen = 1812;
+               vrLoc = 10479;
+       };
+       022B47601218CADD00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B47611218CADD00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47621218CAE000A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 454";
+               rLen = 0;
+               rLoc = 11226;
+               rType = 0;
+               vrLen = 1812;
+               vrLoc = 10479;
+       };
+       022B47651218CDA800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B47661218CDA800A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B47691218CDAE00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B476A1218CDAE00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B476D1218CDBB00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 333";
+               rLen = 0;
+               rLoc = 7480;
+               rType = 0;
+               vrLen = 436;
+               vrLoc = 7125;
+       };
+       022B476E1218CDBB00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 602;
+               vrLoc = 430;
+       };
+       022B476F1218CDBF00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 454";
+               rLen = 0;
+               rLoc = 11226;
+               rType = 0;
+               vrLen = 1812;
+               vrLoc = 10479;
+       };
+       022B47701218CDBF00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535B30C245AEC00CBD4A5 /* DataSourceImager.h */;
+               name = "DataSourceImager.h: 55";
+               rLen = 0;
+               rLoc = 1268;
+               rType = 0;
+               vrLen = 1359;
+               vrLoc = 0;
+       };
+       022B47711218CDBF00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0296A49309D9AE9400F80AFF /* elftosb.cpp */;
+               name = "elftosb.cpp: 574";
+               rLen = 0;
+               rLoc = 14572;
+               rType = 0;
+               vrLen = 2191;
+               vrLoc = 13336;
+       };
+       022B47721218CDBF00A74F96 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0296A49309D9AE9400F80AFF /* elftosb.cpp */;
+               name = "elftosb.cpp: 45";
+               rLen = 0;
+               rLoc = 1198;
+               rType = 0;
+               vrLen = 2551;
+               vrLoc = 428;
+       };
+       0234AF900D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D47A00A16C1E00027E24E /* EncoreBootImageReader.h */;
+               name = "EncoreBootImageReader.h: 34";
+               rLen = 0;
+               rLoc = 863;
+               rType = 0;
+               vrLen = 1721;
+               vrLoc = 682;
+       };
+       0234AF910D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D47A10A16C1E00027E24E /* EncoreBootImageReader.cpp */;
+               name = "EncoreBootImageReader.cpp: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 2023;
+               vrLoc = 3994;
+       };
+       0234AF920D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DDD20A940126003B9C11 /* istream */;
+               name = "istream: 69";
+               rLen = 15;
+               rLoc = 2509;
+               rType = 0;
+               vrLen = 1912;
+               vrLoc = 2126;
+       };
+       0234AF930D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0234AF940D69029300A16BFF /* ios_base.h */;
+               name = "ios_base.h: 392";
+               rLen = 34;
+               rLoc = 13347;
+               rType = 0;
+               vrLen = 1830;
+               vrLoc = 12554;
+       };
+       0234AF940D69029300A16BFF /* ios_base.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = ios_base.h;
+               path = "/Developer/SDKs/MacOSX10.5.sdk/usr/include/c++/4.0.0/bits/ios_base.h";
+               sourceTree = "<absolute>";
+       };
+       0234AF950D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0234AF960D69029300A16BFF /* streambuf */;
+               name = "streambuf: 483";
+               rLen = 62;
+               rLoc = 16527;
+               rType = 0;
+               vrLen = 1541;
+               vrLoc = 15775;
+       };
+       0234AF960D69029300A16BFF /* streambuf */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.cpp.h;
+               name = streambuf;
+               path = "/Developer/SDKs/MacOSX10.5.sdk/usr/include/c++/4.0.0/streambuf";
+               sourceTree = "<absolute>";
+       };
+       0234AF970D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 024F1D600A0BCD8300D21D61 /* ELFSourceFile.h */;
+               name = "ELFSourceFile.h: 127";
+               rLen = 0;
+               rLoc = 3389;
+               rType = 0;
+               vrLen = 2032;
+               vrLoc = 4242;
+       };
+       0234AF9A0D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 024F1D610A0BCD8300D21D61 /* ELFSourceFile.cpp */;
+               name = "ELFSourceFile.cpp: 104";
+               rLen = 32;
+               rLoc = 2168;
+               rType = 0;
+               vrLen = 1442;
+               vrLoc = 4626;
+       };
+       0234AF9C0D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41980A0FF5BF0027E24E /* BootImageGenerator.cpp */;
+               name = "BootImageGenerator.cpp: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1426;
+               vrLoc = 202;
+       };
+       0234AF9D0D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41970A0FF5BF0027E24E /* BootImageGenerator.h */;
+               name = "BootImageGenerator.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1843;
+               vrLoc = 481;
+       };
+       0234AFA00D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 021CA3F10A8D16960028326F /* ExcludesListMatcher.cpp */;
+               name = "ExcludesListMatcher.cpp: 83";
+               rLen = 0;
+               rLoc = 2115;
+               rType = 0;
+               vrLen = 1218;
+               vrLoc = 1018;
+       };
+       0234AFA20D69029300A16BFF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535B30C245AEC00CBD4A5 /* DataSourceImager.h */;
+               name = "DataSourceImager.h: 55";
+               rLen = 0;
+               rLoc = 1268;
+               rType = 0;
+               vrLen = 1251;
+               vrLoc = 108;
+       };
+       024A0F200C53B9D8000317D4 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02D1FD180BD039BF007C7450 /* stl_list.h */;
+               name = erase;
+               rLen = 5;
+               rLoc = 27870;
+               rType = 0;
+               vrLen = 2248;
+               vrLoc = 25661;
+       };
+       024F1D5C0A0BCD7200D21D61 /* SRecordSourceFile.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1288}}";
+                       sepNavSelRange = "{2137, 0}";
+                       sepNavVisRange = "{1103, 1429}";
+                       sepNavVisRect = "{{0, 448}, {706, 782}}";
+               };
+       };
+       024F1D5D0A0BCD7200D21D61 /* SRecordSourceFile.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 2604}}";
+                       sepNavSelRange = "{4100, 0}";
+                       sepNavVisRange = "{0, 1348}";
+                       sepNavVisRect = "{{0, 1822}, {706, 782}}";
+               };
+       };
+       024F1D600A0BCD8300D21D61 /* ELFSourceFile.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 3360}}";
+                       sepNavSelRange = "{3389, 0}";
+                       sepNavVisRange = "{4242, 2032}";
+                       sepNavVisRect = "{{0, 2136}, {706, 782}}";
+               };
+       };
+       024F1D610A0BCD8300D21D61 /* ELFSourceFile.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 7378}}";
+                       sepNavSelRange = "{2168, 32}";
+                       sepNavVisRange = "{4626, 1442}";
+                       sepNavVisRect = "{{0, 2762}, {706, 782}}";
+                       sepNavWindowFrame = "{{15, 63}, {775, 810}}";
+               };
+       };
+       024F1E190A0D20C900D21D61 /* ElftosbErrors.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 782}}";
+                       sepNavSelRange = "{688, 49}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       0258817C0CF13C0400681C7E /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0258817D0CF13C0400681C7E /* backward_warning.h */;
+               name = "backward_warning.h: 32";
+               rLen = 76;
+               rLoc = 1475;
+               rType = 0;
+               vrLen = 1853;
+               vrLoc = 0;
+       };
+       0258817D0CF13C0400681C7E /* backward_warning.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = backward_warning.h;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/backward/backward_warning.h";
+               sourceTree = "<absolute>";
+       };
+       025881810CF13C0400681C7E /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 025881820CF13C0400681C7E /* FlexLexer.h */;
+               name = "FlexLexer.h: 104";
+               rLen = 11;
+               rLoc = 3198;
+               rType = 0;
+               vrLen = 1767;
+               vrLoc = 2593;
+       };
+       025881820CF13C0400681C7E /* FlexLexer.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = FlexLexer.h;
+               path = /Developer/SDKs/MacOSX10.5.sdk/usr/include/FlexLexer.h;
+               sourceTree = "<absolute>";
+       };
+       025881850CF13C0400681C7E /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C08B0A05677000255D31 /* AESKey.cpp */;
+               name = "AESKey.cpp: 26";
+               rLen = 0;
+               rLoc = 968;
+               rType = 0;
+               vrLen = 1825;
+               vrLoc = 280;
+       };
+       025881860CF13C0400681C7E /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02123F370A6B09CF003CF33F /* HexValues.h */;
+               name = "HexValues.h: 14";
+               rLen = 0;
+               rLoc = 471;
+               rType = 0;
+               vrLen = 872;
+               vrLoc = 0;
+       };
+       025881870CF13C0400681C7E /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02FE65860C0522B0004A1450 /* todo.txt */;
+               name = "todo.txt: 13";
+               rLen = 0;
+               rLoc = 281;
+               rType = 0;
+               vrLen = 348;
+               vrLoc = 0;
+       };
+       025881890CF13C0400681C7E /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208BEB10A02D2B800255D31 /* SHA1.cpp */;
+               name = "SHA1.cpp: 132";
+               rLen = 54;
+               rLoc = 4579;
+               rType = 0;
+               vrLen = 1473;
+               vrLoc = 3781;
+       };
+       027402E30A0FB00000CF4BE7 /* GlobMatcher.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 952}}";
+                       sepNavSelRange = "{1227, 0}";
+                       sepNavVisRange = "{353, 1560}";
+                       sepNavVisRect = "{{0, 170}, {706, 782}}";
+               };
+       };
+       027402E40A0FB00000CF4BE7 /* GlobMatcher.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 1932}}";
+                       sepNavSelRange = "{564, 0}";
+                       sepNavVisRect = "{{0, 262}, {706, 782}}";
+               };
+       };
+       027EE3C30BD6930A00A6A136 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41860A0FF0C20027E24E /* OutputSection.cpp */;
+               name = "OutputSection.cpp: 2";
+               rLen = 0;
+               rLoc = 29;
+               rType = 0;
+               vrLen = 507;
+               vrLoc = 0;
+       };
+       027EE3C80BD6930A00A6A136 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 027402E40A0FB00000CF4BE7 /* GlobMatcher.cpp */;
+               name = "GlobMatcher.cpp: NEGATE";
+               rLen = 0;
+               rLoc = 564;
+               rType = 0;
+               vrLen = 1377;
+               vrLoc = 518;
+       };
+       027EE42D0BD6AF1B00A6A136 /* string.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = string.h;
+               path = /Developer/SDKs/MacOSX10.4u.sdk/usr/include/string.h;
+               sourceTree = "<absolute>";
+       };
+       0292B60E0CDA9CFD00A3A500 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD158809F557D300ABE650 /* ElftosbLexer.cpp */;
+               name = "ElftosbLexer.cpp: processStringEscapes";
+               rLen = 0;
+               rLoc = 3573;
+               rType = 0;
+               vrLen = 1665;
+               vrLoc = 1066;
+       };
+       0292B60F0CDA9CFD00A3A500 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D45050A1523350027E24E /* GHSSecInfo.cpp */;
+               name = "GHSSecInfo.cpp: isSectionFilled";
+               rLen = 0;
+               rLoc = 2485;
+               rType = 0;
+               vrLen = 2010;
+               vrLoc = 140;
+       };
+       0292B6100CDA9CFD00A3A500 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E9D67409FBFE98006D7279 /* EvalContext.cpp */;
+               name = "EvalContext::EvalContext()";
+               rLen = 27;
+               rLoc = 575;
+               rType = 0;
+               vrLen = 1382;
+               vrLoc = 0;
+       };
+       0292B6160CDA9CFD00A3A500 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02F8D5600A0152AB004CBE69 /* SourceFile.h */;
+               name = "SourceFile.h: 68";
+               rLen = 0;
+               rLoc = 2070;
+               rType = 0;
+               vrLen = 1924;
+               vrLoc = 2408;
+       };
+       0292B6170CDA9CFD00A3A500 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02FE65040BFE669B004A1450 /* complex.bd */;
+               name = "complex.bd: 92";
+               rLen = 0;
+               rLoc = 1778;
+               rType = 0;
+               vrLen = 1102;
+               vrLoc = 871;
+       };
+       0292B6180CDA9CFD00A3A500 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02F8D5610A0152AB004CBE69 /* SourceFile.cpp */;
+               name = "SourceFile.cpp: 125";
+               rLen = 0;
+               rLoc = 2968;
+               rType = 0;
+               vrLen = 986;
+               vrLoc = 2165;
+       };
+       0296A45509D9AE7A00F80AFF /* elftosb */ = {
+               isa = PBXExecutable;
+               activeArgIndices = (
+                       YES,
+                       YES,
+                       YES,
+                       YES,
+                       YES,
+                       NO,
+                       YES,
+                       NO,
+                       NO,
+                       YES,
+                       YES,
+                       YES,
+                       YES,
+                       NO,
+                       NO,
+                       NO,
+                       YES,
+                       NO,
+                       NO,
+                       YES,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       YES,
+                       YES,
+                       YES,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       YES,
+                       YES,
+                       YES,
+                       YES,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+                       NO,
+               );
+               argumentStrings = (
+                       "-p",
+                       test_files,
+                       "-p",
+                       bdfiles,
+                       "--chip-family",
+                       37xx,
+                       i.MX28,
+                       mx233,
+                       36xx,
+                       "-D",
+                       "testConst=1",
+                       "--debug",
+                       "--verbose",
+                       "-O",
+                       "enableSections=true",
+                       "-q",
+                       "-z",
+                       "-k",
+                       test1.key,
+                       "-c",
+                       habtest.bd,
+                       bdfiles/simple.e,
+                       complex.bd,
+                       bdfiles/complex.bd,
+                       bdfiles/basic_test_cmd.e,
+                       "-o",
+                       output.sb,
+                       test_output/output.sb2,
+                       "-D",
+                       "switchArg1=2",
+                       "-D",
+                       "switchArg2=0",
+                       "newBootMode=5",
+                       test_files/hello_NOR_mixed,
+                       test_files/redboot_gcc.srec,
+                       test_files/hostlink,
+                       test_files/sd_player_gcc,
+                       test_files/sd_player_gcc.srec,
+                       plugin_complex,
+                       test_files/plugin_complex,
+                       test0.key,
+                       test0.key,
+                       ProfileSeedFile50k.bin,
+                       ProfileSeed.bin,
+                       test_files/ProfileSeedFile50k.bin,
+                       test_files/ProfileSeed.bin,
+               );
+               autoAttachOnCrash = 1;
+               breakpointsEnabled = 0;
+               configStateDict = {
+                       "PBXLSLaunchAction-0" = {
+                               PBXLSLaunchAction = 0;
+                               PBXLSLaunchStartAction = 1;
+                               PBXLSLaunchStdioStyle = 2;
+                               PBXLSLaunchStyle = 0;
+                               class = PBXLSRunLaunchConfig;
+                               displayName = "Executable Runner";
+                               identifier = com.apple.Xcode.launch.runConfig;
+                               remoteHostInfo = "";
+                               startActionInfo = "";
+                       };
+               };
+               customDataFormattersEnabled = 1;
+               dataTipCustomDataFormattersEnabled = 1;
+               dataTipShowTypeColumn = 1;
+               dataTipSortType = 0;
+               debuggerPlugin = GDBDebugging;
+               disassemblyDisplayState = 0;
+               dylibVariantSuffix = "";
+               enableDebugStr = 1;
+               environmentEntries = (
+               );
+               executableSystemSymbolLevel = 0;
+               executableUserSymbolLevel = 3;
+               libgmallocEnabled = 0;
+               name = elftosb;
+               savedGlobals = {
+               };
+               showTypeColumn = 0;
+               sourceDirectories = (
+               );
+               startupPath = "<<ProjectDirectory>>";
+               variableFormatDictionary = {
+                       $cs = 1;
+                       $ds = 1;
+                       $eax = 1;
+                       $ebp = 1;
+                       $ebx = 1;
+                       $ecx = 1;
+                       $edi = 1;
+                       $edx = 1;
+                       $eflags = 1;
+                       $eip = 1;
+                       $es = 1;
+                       $esi = 1;
+                       $esp = 1;
+                       $gs = 1;
+                       $mm0 = 1;
+                       $mm1 = 1;
+                       $mm2 = 1;
+                       $mm3 = 1;
+                       $mm4 = 1;
+                       $mm5 = 1;
+                       $mm6 = 1;
+                       $mm7 = 1;
+                       $mxcsr = 1;
+                       $ss = 1;
+                       $xmm0 = 1;
+                       $xmm1 = 1;
+                       $xmm2 = 1;
+                       $xmm3 = 1;
+                       $xmm4 = 1;
+                       $xmm5 = 1;
+                       $xmm6 = 1;
+                       $xmm7 = 1;
+                       "0-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "1-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "10-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "11-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "12-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "13-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "14-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "15-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "2-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "3-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "4-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "5-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "6-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "7-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "8-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "9-uint8_t-elftosbTool::addCryptoKeys" = 1;
+                       "m_identifier-uint32_t-elftosb::EncoreBootImageGenerator::processSectionOptions" = 1;
+                       "m_key-uint8_t [16]-elftosbTool::addCryptoKeys" = 1;
+               };
+       };
+       0296A48709D9AE9400F80AFF /* ELF.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 4858}}";
+                       sepNavSelRange = "{8439, 17}";
+                       sepNavVisRect = "{{0, 3564}, {706, 782}}";
+               };
+       };
+       0296A49309D9AE9400F80AFF /* elftosb.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 10075}}";
+                       sepNavSelRange = "{1198, 0}";
+                       sepNavVisRange = "{428, 2551}";
+                       sepNavVisRect = "{{0, 238}, {706, 782}}";
+               };
+       };
+       0296A49409D9AE9400F80AFF /* elftosb.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 542}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRect = "{{0, 0}, {706, 542}}";
+               };
+       };
+       0296A49E09D9AE9400F80AFF /* stdafx.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {736, 752}}";
+                       sepNavSelRange = "{294, 0}";
+                       sepNavVisRect = "{{0, 0}, {736, 752}}";
+               };
+       };
+       0296A49F09D9AE9400F80AFF /* StELFFile.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {701, 7630}}";
+                       sepNavSelRange = "{12530, 0}";
+                       sepNavVisRect = "{{0, 4707}, {701, 764}}";
+               };
+       };
+       0296A4A009D9AE9400F80AFF /* StELFFile.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 2870}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{0, 1545}";
+                       sepNavVisRect = "{{0, 1514}, {706, 542}}";
+               };
+       };
+       0296A4A409D9AE9400F80AFF /* StExecutableImage.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 6622}}";
+                       sepNavSelRange = "{6397, 0}";
+                       sepNavVisRect = "{{0, 2800}, {732, 782}}";
+               };
+       };
+       0296A4A509D9AE9400F80AFF /* StExecutableImage.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 3640}}";
+                       sepNavSelRange = "{2539, 57}";
+                       sepNavVisRange = "{1155, 2120}";
+                       sepNavVisRect = "{{0, 2177}, {742, 782}}";
+               };
+       };
+       0296A4AA09D9AE9400F80AFF /* StSRecordFile.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 3402}}";
+                       sepNavSelRange = "{2909, 0}";
+                       sepNavVisRect = "{{0, 2058}, {732, 782}}";
+               };
+       };
+       0296A4AB09D9AE9400F80AFF /* StSRecordFile.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1792}}";
+                       sepNavSelRange = "{3611, 0}";
+                       sepNavVisRange = "{2223, 1584}";
+                       sepNavVisRect = "{{0, 1010}, {706, 782}}";
+               };
+       };
+       0296A50409D9AE9400F80AFF /* Source Control */ = {
+               isa = PBXSourceControlManager;
+               fallbackIsa = XCSourceControlManager;
+               isSCMEnabled = 0;
+               scmConfiguration = {
+                       repositoryName = himikoip;
+                       repositoryNamesForRoots = {
+                               "" = "psg-firmware";
+                       };
+               };
+               scmType = scm.subversion;
+       };
+       0296A50509D9AE9400F80AFF /* Code sense */ = {
+               isa = PBXCodeSenseManager;
+               indexTemplatePath = "";
+       };
+       0296CF9C09DB3C5200F80AFF /* stdafx.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {740, 1092}}";
+                       sepNavSelRange = "{1626, 0}";
+                       sepNavVisRange = "{0, 2167}";
+                       sepNavVisRect = "{{0, 372}, {732, 782}}";
+               };
+       };
+       02B9D4FB0B9A13AE0084CE1F /* SB36xxBootImageGenerator.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 826}}";
+                       sepNavSelRange = "{1395, 0}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       02B9D4FC0B9A13AE0084CE1F /* SB36xxBootImageGenerator.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 3402}}";
+                       sepNavSelRange = "{3994, 0}";
+                       sepNavVisRect = "{{0, 1262}, {706, 782}}";
+               };
+       };
+       02B9D5020B9A16C10084CE1F /* St3600IPL.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 11746}}";
+                       sepNavSelRange = "{21214, 23}";
+                       sepNavVisRange = "{21696, 1756}";
+                       sepNavVisRect = "{{0, 9338}, {706, 782}}";
+               };
+       };
+       02B9D5030B9A16C10084CE1F /* St3600IPL.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {740, 5044}}";
+                       sepNavSelRange = "{2516, 135}";
+                       sepNavVisRange = "{1241, 2955}";
+                       sepNavVisRect = "{{0, 3086}, {706, 782}}";
+               };
+       };
+       02B9D5060B9A16C10084CE1F /* StKeySet.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {742, 938}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRect = "{{0, 129}, {742, 782}}";
+               };
+       };
+       02B9D5090B9A16C10084CE1F /* table.c */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 18424}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       02B9D56B0B9B37890084CE1F /* default_rom_key.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {742, 782}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRect = "{{0, 0}, {742, 782}}";
+               };
+       };
+       02C5DB910A925C61003B9C11 /* format_string.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 778}}";
+                       sepNavSelRange = "{649, 0}";
+                       sepNavVisRange = "{0, 734}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       02C5DB920A925C61003B9C11 /* format_string.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {683, 1079}}";
+                       sepNavSelRange = "{602, 0}";
+                       sepNavVisRange = "{478, 290}";
+                       sepNavVisRect = "{{0, 247}, {706, 782}}";
+               };
+       };
+       02C5DBD20A926A7F003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DBD30A926A7F003B9C11 /* stdarg.h */;
+               name = "(null): 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1796;
+               vrLoc = 761;
+       };
+       02C5DBD30A926A7F003B9C11 /* stdarg.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = stdarg.h;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/gcc/i686-apple-darwin8/4.0.1/include/stdarg.h";
+               sourceTree = "<absolute>";
+       };
+       02C5DBD50A926A7F003B9C11 /* stdio.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = stdio.h;
+               path = /Developer/SDKs/MacOSX10.4u.sdk/usr/include/stdio.h;
+               sourceTree = "<absolute>";
+       };
+       02C5DBDB0A926A7F003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 024F1E190A0D20C900D21D61 /* ElftosbErrors.h */;
+               name = "ElftosbErrors.h: semantic_error";
+               rLen = 0;
+               rLoc = 827;
+               rType = 0;
+               vrLen = 885;
+               vrLoc = 0;
+       };
+       02C5DC000A93AC85003B9C11 /* EndianUtilities.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 2100}}";
+                       sepNavSelRange = "{2183, 0}";
+                       sepNavVisRange = "{3291, 1685}";
+                       sepNavVisRect = "{{0, 93}, {706, 782}}";
+               };
+       };
+       02C5DC310A93C14E003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DC320A93C14E003B9C11 /* Endian.h */;
+               name = "(null): 126";
+               rLen = 0;
+               rLoc = 4144;
+               rType = 0;
+               vrLen = 2784;
+               vrLoc = 5362;
+       };
+       02C5DC320A93C14E003B9C11 /* Endian.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = Endian.h;
+               path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/Endian.h;
+               sourceTree = "<absolute>";
+       };
+       02C5DC330A93C14E003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DC340A93C14E003B9C11 /* TargetConditionals.h */;
+               name = "#if defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__) )";
+               rLen = 106;
+               rLoc = 2474;
+               rType = 0;
+               vrLen = 2403;
+               vrLoc = 1435;
+       };
+       02C5DC340A93C14E003B9C11 /* TargetConditionals.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = TargetConditionals.h;
+               path = /Developer/SDKs/MacOSX10.4u.sdk/usr/include/TargetConditionals.h;
+               sourceTree = "<absolute>";
+       };
+       02C5DC350A93C14E003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DC360A93C14E003B9C11 /* ConditionalMacros.h */;
+               name = TargetConditionals.h;
+               rLen = 20;
+               rLoc = 1458;
+               rType = 0;
+               vrLen = 2328;
+               vrLoc = 333;
+       };
+       02C5DC360A93C14E003B9C11 /* ConditionalMacros.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = ConditionalMacros.h;
+               path = /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/ConditionalMacros.h;
+               sourceTree = "<absolute>";
+       };
+       02C5DCB50A93CA0A003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0296A4A409D9AE9400F80AFF /* StExecutableImage.cpp */;
+               name = "StExecutableImage.cpp: 209";
+               rLen = 0;
+               rLoc = 6397;
+               rType = 0;
+               vrLen = 1942;
+               vrLoc = 5927;
+       };
+       02C5DD520A93D327003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0296A4AA09D9AE9400F80AFF /* StSRecordFile.cpp */;
+               name = "StSRecordFile.cpp: 115";
+               rLen = 0;
+               rLoc = 2909;
+               rType = 0;
+               vrLen = 1505;
+               vrLoc = 3910;
+       };
+       02C5DDCD0A940126003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DDCE0A940126003B9C11 /* ctype.h */;
+               name = "(null): 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 1755;
+               vrLoc = 4602;
+       };
+       02C5DDCE0A940126003B9C11 /* ctype.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = ctype.h;
+               path = /Developer/SDKs/MacOSX10.4u.sdk/usr/include/ctype.h;
+               sourceTree = "<absolute>";
+       };
+       02C5DDCF0A940126003B9C11 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02123F380A6B09CF003CF33F /* HexValues.cpp */;
+               name = "HexValues.cpp: 38";
+               rLen = 0;
+               rLoc = 1007;
+               rType = 0;
+               vrLen = 1135;
+               vrLoc = 0;
+       };
+       02C5DDD20A940126003B9C11 /* istream */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.cpp.h;
+               name = istream;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/istream";
+               sourceTree = "<absolute>";
+       };
+       02CAC9BA0BA06EA50020B29B /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CAC9BB0BA06EA50020B29B /* stdexcept */;
+               name = invalid_argument;
+               rLen = 16;
+               rLoc = 2759;
+               rType = 0;
+               vrLen = 2133;
+               vrLoc = 1621;
+       };
+       02CAC9BB0BA06EA50020B29B /* stdexcept */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.cpp.h;
+               name = stdexcept;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/stdexcept";
+               sourceTree = "<absolute>";
+       };
+       02CD157309F543FE00ABE650 /* ElftosbAST.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 16107}}";
+                       sepNavSelRange = "{29207, 13}";
+                       sepNavVisRange = "{28110, 2093}";
+                       sepNavVisRect = "{{0, 5658}, {706, 782}}";
+               };
+       };
+       02CD157409F543FE00ABE650 /* ElftosbAST.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {683, 17771}}";
+                       sepNavSelRange = "{7480, 0}";
+                       sepNavVisRange = "{7125, 436}";
+                       sepNavVisRect = "{{0, 7297}, {706, 782}}";
+               };
+       };
+       02CD158809F557D300ABE650 /* ElftosbLexer.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 2212}}";
+                       sepNavSelRange = "{3573, 0}";
+                       sepNavVisRect = "{{0, 606}, {706, 782}}";
+               };
+       };
+       02D1FCA70BD02B69007C7450 /* SearchPath.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 938}}";
+                       sepNavSelRange = "{1478, 0}";
+                       sepNavVisRange = "{282, 1401}";
+                       sepNavVisRect = "{{0, 148}, {706, 782}}";
+               };
+       };
+       02D1FCA80BD02B69007C7450 /* SearchPath.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1792}}";
+                       sepNavSelRange = "{1816, 0}";
+                       sepNavVisRange = "{1353, 1637}";
+                       sepNavVisRect = "{{0, 546}, {706, 782}}";
+               };
+       };
+       02D1FD180BD039BF007C7450 /* stl_list.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = stl_list.h;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_list.h";
+               sourceTree = "<absolute>";
+       };
+       02D1FD190BD039BF007C7450 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DBD50A926A7F003B9C11 /* stdio.h */;
+               name = fopen;
+               rLen = 5;
+               rLoc = 9282;
+               rType = 0;
+               vrLen = 2059;
+               vrLoc = 8686;
+       };
+       02D1FE2E0BD1505E007C7450 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02B9D4FB0B9A13AE0084CE1F /* SB36xxBootImageGenerator.h */;
+               name = "SB36xxBootImageGenerator.h: processOptions";
+               rLen = 0;
+               rLoc = 1395;
+               rType = 0;
+               vrLen = 1805;
+               vrLoc = 0;
+       };
+       02D46C100FED492400E65706 /* elftosb_lexer.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {683, 29055}}";
+                       sepNavSelRange = "{64618, 0}";
+                       sepNavVisRange = "{43654, 237}";
+               };
+       };
+       02D46C110FED492400E65706 /* elftosb_parser.tab.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {683, 39182}}";
+                       sepNavSelRange = "{3846, 0}";
+                       sepNavVisRange = "{3210, 297}";
+               };
+       };
+       02D46C120FED492400E65706 /* elftosb_parser.tab.hpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {740, 1976}}";
+                       sepNavSelRange = "{201, 0}";
+                       sepNavVisRange = "{2150, 1900}";
+               };
+       };
+       02D46C3B0FED5C3600E65706 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535B40C245AEC00CBD4A5 /* DataSourceImager.cpp */;
+               name = "DataSourceImager.cpp: 93";
+               rLen = 0;
+               rLoc = 2416;
+               rType = 0;
+               vrLen = 1639;
+               vrLoc = 2038;
+       };
+       02D46C3F0FED5C3600E65706 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02B9D5020B9A16C10084CE1F /* St3600IPL.cpp */;
+               name = "St3600IPL.cpp: 627";
+               rLen = 23;
+               rLoc = 21214;
+               rType = 0;
+               vrLen = 1756;
+               vrLoc = 21696;
+       };
+       02D46C690FED5F4B00E65706 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02FE65050BFE669B004A1450 /* simple.e */;
+               name = "simple.e: 2";
+               rLen = 0;
+               rLoc = 12;
+               rType = 0;
+               vrLen = 112;
+               vrLoc = 0;
+       };
+       02D46D1A0FED80BF00E65706 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02F8D41C09FE86FA004CBE69 /* EncoreBootImage.cpp */;
+               name = "EncoreBootImage.cpp: 857";
+               rLen = 0;
+               rLoc = 29517;
+               rType = 0;
+               vrLen = 1960;
+               vrLoc = 28758;
+       };
+       02D6132E10F28A6500B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02D46C100FED492400E65706 /* elftosb_lexer.cpp */;
+               name = "elftosb_lexer.cpp: 327";
+               rLen = 6;
+               rLoc = 9110;
+               rType = 0;
+               vrLen = 2447;
+               vrLoc = 8031;
+       };
+       02D6132F10F28A6500B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */;
+               name = "elftosb_lexer.l: 6";
+               rLen = 12;
+               rLoc = 104;
+               rType = 0;
+               vrLen = 2015;
+               vrLoc = 0;
+       };
+       02D6133010F28A6500B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3BA09F3FBF100EA7C45 /* ElftosbLexer.h */;
+               name = "ElftosbLexer.h: 65";
+               rLen = 11;
+               rLoc = 1845;
+               rType = 0;
+               vrLen = 2353;
+               vrLoc = 695;
+       };
+       02D6138C10F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E3998909F2ED990055992A /* FlexLexer.h */;
+               name = "FlexLexer.h: 107";
+               rLen = 0;
+               rLoc = 3394;
+               rType = 0;
+               vrLen = 2605;
+               vrLoc = 3015;
+       };
+       02D6138D10F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41B80A0FFD140027E24E /* EncoreBootImageGenerator.cpp */;
+               name = "EncoreBootImageGenerator.cpp: 279";
+               rLen = 0;
+               rLoc = 7882;
+               rType = 0;
+               vrLen = 2263;
+               vrLoc = 6290;
+       };
+       02D6138E10F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41B70A0FFD140027E24E /* EncoreBootImageGenerator.h */;
+               name = "EncoreBootImageGenerator.h: 31";
+               rLen = 0;
+               rLoc = 918;
+               rType = 0;
+               vrLen = 2176;
+               vrLoc = 0;
+       };
+       02D6138F10F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157309F543FE00ABE650 /* ElftosbAST.h */;
+               name = "ElftosbAST.h: 955";
+               rLen = 0;
+               rLoc = 25686;
+               rType = 0;
+               vrLen = 2192;
+               vrLoc = 0;
+       };
+       02D6139010F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02D46C120FED492400E65706 /* elftosb_parser.tab.hpp */;
+               name = "elftosb_parser.tab.hpp: 5";
+               rLen = 0;
+               rLoc = 201;
+               rType = 0;
+               vrLen = 1900;
+               vrLoc = 2150;
+       };
+       02D6139110F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02B9D5030B9A16C10084CE1F /* St3600IPL.h */;
+               name = "St3600IPL.h: 91";
+               rLen = 135;
+               rLoc = 2516;
+               rType = 0;
+               vrLen = 2955;
+               vrLoc = 1241;
+       };
+       02D6139210F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C29A0A0A4EE800255D31 /* ConversionController.h */;
+               name = "ConversionController.h: 72";
+               rLen = 0;
+               rLoc = 2407;
+               rType = 0;
+               vrLen = 3032;
+               vrLoc = 1610;
+       };
+       02D6139310F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */;
+               name = "elftosb_parser.y: 565";
+               rLen = 0;
+               rLoc = 14295;
+               rType = 0;
+               vrLen = 2554;
+               vrLoc = 2578;
+       };
+       02D6139410F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */;
+               name = "ConversionController.cpp: 40";
+               rLen = 27;
+               rLoc = 1209;
+               rType = 0;
+               vrLen = 2268;
+               vrLoc = 0;
+       };
+       02D6139510F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02FE65030BFE669B004A1450 /* basic_test_cmd.e */;
+               name = "basic_test_cmd.e: 45";
+               rLen = 4;
+               rLoc = 746;
+               rType = 0;
+               vrLen = 1164;
+               vrLoc = 319;
+       };
+       02D6139610F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0296A49309D9AE9400F80AFF /* elftosb.cpp */;
+               name = "elftosb.cpp: 572";
+               rLen = 0;
+               rLoc = 14572;
+               rType = 0;
+               vrLen = 2113;
+               vrLoc = 13347;
+       };
+       02D6139710F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02123F2F0A6B057E003CF33F /* Blob.h */;
+               name = "Blob.h: 65";
+               rLen = 0;
+               rLoc = 1584;
+               rType = 0;
+               vrLen = 1876;
+               vrLoc = 0;
+       };
+       02D6139810F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0296CF9C09DB3C5200F80AFF /* stdafx.h */;
+               name = "stdafx.h: 56";
+               rLen = 0;
+               rLoc = 1626;
+               rType = 0;
+               vrLen = 2167;
+               vrLoc = 0;
+       };
+       02D6139910F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02D6139A10F3E89000B7DF2F /* string.h */;
+               name = "string.h: 83";
+               rLen = 44;
+               rLoc = 3369;
+               rType = 0;
+               vrLen = 2973;
+               vrLoc = 2024;
+       };
+       02D6139A10F3E89000B7DF2F /* string.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = string.h;
+               path = /Developer/SDKs/MacOSX10.5.sdk/usr/include/string.h;
+               sourceTree = "<absolute>";
+       };
+       02D6139B10F3E89000B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02123F300A6B057E003CF33F /* Blob.cpp */;
+               name = "Blob.cpp: 33";
+               rLen = 6;
+               rLoc = 784;
+               rType = 0;
+               vrLen = 1973;
+               vrLoc = 0;
+       };
+       02D6139F10F3E96300B7DF2F /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02123F300A6B057E003CF33F /* Blob.cpp */;
+               name = "Blob.cpp: 52";
+               rLen = 4;
+               rLoc = 1143;
+               rType = 0;
+               vrLen = 1990;
+               vrLoc = 0;
+       };
+       02D795420FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D46830A1665D90027E24E /* sbtool.cpp */;
+               name = "sbtool.cpp: 33";
+               rLen = 0;
+               rLoc = 844;
+               rType = 0;
+               vrLen = 1414;
+               vrLoc = 23;
+       };
+       02D795430FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E25EA90A1A5DCB001161B5 /* keygen.cpp */;
+               name = "keygen.cpp: 36";
+               rLen = 0;
+               rLoc = 949;
+               rType = 0;
+               vrLen = 1579;
+               vrLoc = 23;
+       };
+       02D795440FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */;
+               name = "ElftosbAST.cpp: 1129";
+               rLen = 0;
+               rLoc = 27632;
+               rType = 0;
+               vrLen = 1350;
+               vrLoc = 26432;
+       };
+       02D795450FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02F8D41B09FE86FA004CBE69 /* EncoreBootImage.h */;
+               name = "EncoreBootImage.h: 670";
+               rLen = 0;
+               rLoc = 25015;
+               rType = 0;
+               vrLen = 1962;
+               vrLoc = 24513;
+       };
+       02D795460FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */;
+               name = "Operation.cpp: 29";
+               rLen = 9;
+               rLoc = 753;
+               rType = 0;
+               vrLen = 1237;
+               vrLoc = 0;
+       };
+       02D795470FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */;
+               name = "format_string.cpp: 28";
+               rLen = 15;
+               rLoc = 751;
+               rType = 0;
+               vrLen = 1232;
+               vrLoc = 801;
+       };
+       02D795480FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02C5DB910A925C61003B9C11 /* format_string.h */;
+               name = "format_string.h: 23";
+               rLen = 0;
+               rLoc = 649;
+               rType = 0;
+               vrLen = 734;
+               vrLoc = 0;
+       };
+       02D795490FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02D1FCA80BD02B69007C7450 /* SearchPath.cpp */;
+               name = "SearchPath.cpp: 57";
+               rLen = 0;
+               rLoc = 1816;
+               rType = 0;
+               vrLen = 1637;
+               vrLoc = 1353;
+       };
+       02D7954A0FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28D0A0A4E5F00255D31 /* DataTarget.h */;
+               name = "DataTarget.h: 72";
+               rLen = 0;
+               rLoc = 2252;
+               rType = 0;
+               vrLen = 1982;
+               vrLoc = 2339;
+       };
+       02D7954D0FF00D8B00C1C5DF /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C28B0A0A4E5F00255D31 /* Operation.h */;
+               name = "Operation.h: 73";
+               rLen = 0;
+               rLoc = 1618;
+               rType = 0;
+               vrLen = 1240;
+               vrLoc = 1197;
+       };
+       02DC603C0A7AAA7A0027E7F9 /* index.html */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 782}}";
+                       sepNavSelRange = "{303, 0}";
+                       sepNavVisRect = "{{0, 0}, {732, 782}}";
+               };
+       };
+       02E25EA40A1A5DB0001161B5 /* keygen */ = {
+               activeExec = 0;
+               executables = (
+                       02E25EA60A1A5DB0001161B5 /* keygen */,
+               );
+       };
+       02E25EA60A1A5DB0001161B5 /* keygen */ = {
+               isa = PBXExecutable;
+               activeArgIndices = (
+               );
+               argumentStrings = (
+               );
+               autoAttachOnCrash = 1;
+               breakpointsEnabled = 1;
+               configStateDict = {
+               };
+               customDataFormattersEnabled = 1;
+               dataTipCustomDataFormattersEnabled = 1;
+               dataTipShowTypeColumn = 1;
+               dataTipSortType = 0;
+               debuggerPlugin = GDBDebugging;
+               disassemblyDisplayState = 0;
+               enableDebugStr = 1;
+               environmentEntries = (
+               );
+               executableSystemSymbolLevel = 0;
+               executableUserSymbolLevel = 0;
+               libgmallocEnabled = 0;
+               name = keygen;
+               showTypeColumn = 0;
+               sourceDirectories = (
+               );
+       };
+       02E25EA90A1A5DCB001161B5 /* keygen.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 4788}}";
+                       sepNavSelRange = "{949, 0}";
+                       sepNavVisRange = "{23, 1579}";
+                       sepNavVisRect = "{{0, 64}, {732, 782}}";
+                       sepNavWindowFrame = "{{15, 63}, {775, 810}}";
+               };
+       };
+       02E3997909F2E0410055992A /* elftosb_lexer.l */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 3939}}";
+                       sepNavSelRange = "{1417, 0}";
+                       sepNavVisRange = "{3894, 1528}";
+                       sepNavVisRect = "{{0, 3362}, {706, 782}}";
+                       sepNavWindowFrame = "{{15, 0}, {671, 1178}}";
+               };
+       };
+       02E3998909F2ED990055992A /* FlexLexer.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {731, 2717}}";
+                       sepNavSelRange = "{6344, 0}";
+                       sepNavVisRange = "{4228, 930}";
+                       sepNavVisRect = "{{0, 1465}, {745, 388}}";
+               };
+       };
+       02E3998D09F2EFAA0055992A /* rijndael.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 22526}}";
+                       sepNavSelRange = "{72196, 0}";
+                       sepNavVisRect = "{{0, 14532}, {732, 782}}";
+               };
+       };
+       02E3998E09F2EFAA0055992A /* rijndael.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {732, 2240}}";
+                       sepNavSelRange = "{1812, 0}";
+                       sepNavVisRect = "{{0, 1458}, {732, 782}}";
+               };
+       };
+       02E535B30C245AEC00CBD4A5 /* DataSourceImager.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 1076}}";
+                       sepNavSelRange = "{1268, 0}";
+                       sepNavVisRange = "{0, 1359}";
+                       sepNavVisRect = "{{0, 84}, {706, 782}}";
+               };
+       };
+       02E535B40C245AEC00CBD4A5 /* DataSourceImager.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 1950}}";
+                       sepNavSelRange = "{512, 40}";
+                       sepNavVisRange = "{482, 2065}";
+                       sepNavVisRect = "{{0, 1304}, {706, 782}}";
+               };
+       };
+       02E535CF0C24641A00CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 027EE42D0BD6AF1B00A6A136 /* string.h */;
+               name = "size_t\t strlen(const char *);";
+               rLen = 30;
+               rLoc = 3873;
+               rType = 0;
+               vrLen = 1824;
+               vrLoc = 3059;
+       };
+       02E535D00C24641A00CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535D10C24641A00CBD4A5 /* algorithm */;
+               name = bits/stl_algobase.h;
+               rLen = 19;
+               rLoc = 2669;
+               rType = 0;
+               vrLen = 2194;
+               vrLoc = 624;
+       };
+       02E535D10C24641A00CBD4A5 /* algorithm */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.cpp.h;
+               name = algorithm;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/algorithm";
+               sourceTree = "<absolute>";
+       };
+       02E535D20C24641A00CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535D30C24641A00CBD4A5 /* string */;
+               name = bits/basic_string.h;
+               rLen = 19;
+               rLoc = 1984;
+               rType = 0;
+               vrLen = 2016;
+               vrLoc = 132;
+       };
+       02E535D30C24641A00CBD4A5 /* string */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.cpp.h;
+               name = string;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/string";
+               sourceTree = "<absolute>";
+       };
+       02E535D40C24641A00CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535D50C24641A00CBD4A5 /* basic_string.h */;
+               name = begin;
+               rLen = 5;
+               rLoc = 16411;
+               rType = 0;
+               vrLen = 1129;
+               vrLoc = 15813;
+       };
+       02E535D50C24641A00CBD4A5 /* basic_string.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = basic_string.h;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/basic_string.h";
+               sourceTree = "<absolute>";
+       };
+       02E535D70C24641A00CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535D80C24641A00CBD4A5 /* stl_algobase.h */;
+               name = lexicographical_compare;
+               rLen = 23;
+               rLoc = 27547;
+               rType = 0;
+               vrLen = 1663;
+               vrLoc = 29305;
+       };
+       02E535D80C24641A00CBD4A5 /* stl_algobase.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = stl_algobase.h;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_algobase.h";
+               sourceTree = "<absolute>";
+       };
+       02E535D90C24641A00CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535DA0C24641A00CBD4A5 /* stl_algo.h */;
+               name = find;
+               rLen = 4;
+               rLoc = 8733;
+               rType = 0;
+               vrLen = 1567;
+               vrLoc = 8131;
+       };
+       02E535DA0C24641A00CBD4A5 /* stl_algo.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = stl_algo.h;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_algo.h";
+               sourceTree = "<absolute>";
+       };
+       02E535DC0C24641A00CBD4A5 /* stl_map.h */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.c.h;
+               name = stl_map.h;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/bits/stl_map.h";
+               sourceTree = "<absolute>";
+       };
+       02E535DE0C24641A00CBD4A5 /* map */ = {
+               isa = PBXFileReference;
+               lastKnownFileType = sourcecode.cpp.h;
+               name = map;
+               path = "/Developer/SDKs/MacOSX10.4u.sdk/usr/include/c++/4.0.0/map";
+               sourceTree = "<absolute>";
+       };
+       02E535F10C24641A00CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D41850A0FF0C20027E24E /* OutputSection.h */;
+               name = "OutputSection.h: 21";
+               rLen = 0;
+               rLoc = 625;
+               rType = 0;
+               vrLen = 1572;
+               vrLoc = 647;
+       };
+       02E5362D0C38763700CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02F8D5490A014F5D004CBE69 /* Value.h */;
+               name = "Value.h: 133";
+               rLen = 0;
+               rLoc = 4209;
+               rType = 0;
+               vrLen = 1390;
+               vrLoc = 531;
+       };
+       02E536320C38763700CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 020D416A0A0FE8AC0027E24E /* StringMatcher.h */;
+               name = "StringMatcher.h: 42";
+               rLen = 0;
+               rLoc = 1117;
+               rType = 0;
+               vrLen = 1426;
+               vrLoc = 514;
+       };
+       02E536340C38763700CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2880A0A4E5F00255D31 /* DataSource.cpp */;
+               name = "DataSource.cpp: 50";
+               rLen = 0;
+               rLoc = 1464;
+               rType = 0;
+               vrLen = 1494;
+               vrLoc = 570;
+       };
+       02E536350C38763700CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0208C2890A0A4E5F00255D31 /* DataSource.h */;
+               name = "DataSource.h: 113";
+               rLen = 0;
+               rLoc = 3693;
+               rType = 0;
+               vrLen = 1872;
+               vrLoc = 2865;
+       };
+       02E536360C38763700CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535DE0C24641A00CBD4A5 /* map */;
+               name = bits/stl_map.;
+               rLen = 13;
+               rLoc = 2682;
+               rType = 0;
+               vrLen = 1967;
+               vrLoc = 841;
+       };
+       02E5363F0C3C4FF000CBD4A5 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 02E535DC0C24641A00CBD4A5 /* stl_map.h */;
+               name = erase;
+               rLen = 5;
+               rLoc = 15389;
+               rType = 0;
+               vrLen = 2055;
+               vrLoc = 11183;
+       };
+       02E9D5B009FA8AE4006D7279 /* smart_ptr.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 3262}}";
+                       sepNavSelRange = "{1953, 0}";
+                       sepNavVisRange = "{0, 1477}";
+                       sepNavVisRect = "{{0, 208}, {706, 542}}";
+               };
+       };
+       02E9D67309FBFE97006D7279 /* EvalContext.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1540}}";
+                       sepNavSelRange = "{1402, 26}";
+                       sepNavVisRange = "{874, 1518}";
+                       sepNavVisRect = "{{0, 364}, {706, 782}}";
+               };
+       };
+       02E9D67409FBFE98006D7279 /* EvalContext.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 1680}}";
+                       sepNavSelRange = "{575, 27}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       02F8D41B09FE86FA004CBE69 /* EncoreBootImage.h */ = {
+               uiCtxt = {
+                       sepNavFolds = "{\n    c =     (\n                {\n            r = \"{12406, 1422}\";\n            s = 0;\n        },\n                {\n            r = \"{17593, 599}\";\n            s = 0;\n        },\n                {\n            r = \"{18291, 1349}\";\n            s = 0;\n        },\n                {\n            r = \"{21868, 1241}\";\n            s = 0;\n        },\n                {\n            r = \"{23214, 821}\";\n            s = 0;\n        },\n                {\n            r = \"{26522, 2695}\";\n            s = 0;\n        },\n                {\n            r = \"{29325, 2002}\";\n            s = 0;\n        },\n                {\n            r = \"{31439, 1052}\";\n            s = 0;\n        }\n    );\n    r = \"{0, 35984}\";\n    s = 0;\n}";
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 9912}}";
+                       sepNavSelRange = "{19588, 0}";
+                       sepNavVisRange = "{19086, 1962}";
+                       sepNavVisRect = "{{0, 1867}, {706, 782}}";
+               };
+       };
+       02F8D41C09FE86FA004CBE69 /* EncoreBootImage.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 19460}}";
+                       sepNavSelRange = "{37227, 0}";
+                       sepNavVisRange = "{34594, 1909}";
+                       sepNavVisRect = "{{0, 4734}, {706, 782}}";
+               };
+       };
+       02F8D46509FEA584004CBE69 /* AESKey.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 2142}}";
+                       sepNavSelRange = "{3236, 0}";
+                       sepNavVisRange = "{2384, 1593}";
+                       sepNavVisRect = "{{0, 1235}, {648, 764}}";
+               };
+       };
+       02F8D4EF09FEE91B004CBE69 /* crc.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {736, 2450}}";
+                       sepNavSelRange = "{7654, 0}";
+                       sepNavVisRect = "{{0, 1632}, {736, 782}}";
+               };
+       };
+       02F8D4F009FEE91B004CBE69 /* crc.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {811, 798}}";
+                       sepNavSelRange = "{814, 13}";
+                       sepNavVisRect = "{{0, 316}, {811, 482}}";
+               };
+       };
+       02F8D5490A014F5D004CBE69 /* Value.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {706, 2058}}";
+                       sepNavSelRange = "{4209, 0}";
+                       sepNavVisRect = "{{0, 260}, {706, 782}}";
+               };
+       };
+       02F8D54A0A014F5D004CBE69 /* Value.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {753, 782}}";
+                       sepNavSelRange = "{1161, 0}";
+                       sepNavVisRect = "{{0, 0}, {753, 782}}";
+               };
+       };
+       02F8D5600A0152AB004CBE69 /* SourceFile.h */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {810, 2119}}";
+                       sepNavSelRange = "{3395, 20}";
+                       sepNavVisRange = "{1842, 2643}";
+                       sepNavVisRect = "{{0, 1134}, {706, 782}}";
+                       sepNavWindowFrame = "{{15, -5}, {777, 878}}";
+               };
+       };
+       02F8D5610A0152AB004CBE69 /* SourceFile.cpp */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {745, 2618}}";
+                       sepNavSelRange = "{2877, 0}";
+                       sepNavVisRect = "{{0, 1258}, {745, 764}}";
+               };
+       };
+       02F8D5DC0A01A38A004CBE69 /* PBXCPPExceptionBreakpoint */ = {
+               isa = PBXCPPExceptionBreakpoint;
+               actions = (
+               );
+               breakpointStyle = 0;
+               condition = 02F8D5DD0A01A3A8004CBE69 /* XCCPPCondition */;
+               continueAfterActions = 1;
+               countType = 0;
+               delayBeforeContinue = 0;
+               exceptionName = $;
+               hitCount = 0;
+               ignoreCount = 0;
+               isThrow = 1;
+               modificationTime = 267302557.4579;
+               originalNumberOfMultipleMatches = 0;
+               state = 2;
+       };
+       02F8D5DD0A01A3A8004CBE69 /* XCCPPCondition */ = {
+               isa = XCCPPCondition;
+               conditionString = "On Throw";
+       };
+       02FE65030BFE669B004A1450 /* basic_test_cmd.e */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {740, 2132}}";
+                       sepNavSelRange = "{746, 4}";
+                       sepNavVisRange = "{319, 1164}";
+               };
+       };
+       02FE65040BFE669B004A1450 /* complex.bd */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 3668}}";
+                       sepNavSelRange = "{1471, 33}";
+                       sepNavVisRange = "{975, 1067}";
+                       sepNavVisRect = "{{0, 2716}, {706, 782}}";
+               };
+       };
+       02FE65050BFE669B004A1450 /* simple.e */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 778}}";
+                       sepNavSelRange = "{12, 0}";
+                       sepNavVisRange = "{0, 112}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       02FE65060BFE669B004A1450 /* test_cmd.e */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 1694}}";
+                       sepNavSelRange = "{0, 0}";
+                       sepNavVisRange = "{0, 914}";
+                       sepNavVisRect = "{{0, 168}, {706, 782}}";
+               };
+       };
+       02FE651B0BFF94B2004A1450 /* PBXTextBookmark */ = {
+               isa = PBXTextBookmark;
+               fRef = 0296A49409D9AE9400F80AFF /* elftosb.h */;
+               name = "elftosb.h: 1";
+               rLen = 0;
+               rLoc = 0;
+               rType = 0;
+               vrLen = 757;
+               vrLoc = 0;
+       };
+       02FE65860C0522B0004A1450 /* todo.txt */ = {
+               uiCtxt = {
+                       sepNavIntBoundsRect = "{{0, 0}, {692, 779}}";
+                       sepNavSelRange = "{281, 0}";
+                       sepNavVisRange = "{0, 348}";
+                       sepNavVisRect = "{{0, 0}, {706, 782}}";
+               };
+       };
+       08FB7793FE84155DC02AAC07 /* Project object */ = {
+               activeBuildConfigurationName = Debug;
+               activeExecutable = 0296A45509D9AE7A00F80AFF /* elftosb */;
+               activeTarget = 8DD76F620486A84900D96B5E /* elftosb */;
+               addToTargets = (
+                       8DD76F620486A84900D96B5E /* elftosb */,
+               );
+               breakpoints = (
+                       02F8D5DC0A01A38A004CBE69 /* PBXCPPExceptionBreakpoint */,
+                       020DDCA30A1E32A400E1CB49 /* PBXCPPExceptionBreakpoint */,
+               );
+               codeSenseManager = 0296A50509D9AE9400F80AFF /* Code sense */;
+               executables = (
+                       0296A45509D9AE7A00F80AFF /* elftosb */,
+                       020D467C0A16657C0027E24E /* sbtool */,
+                       02E25EA60A1A5DB0001161B5 /* keygen */,
+               );
+               expressions = (
+                       "(SRecordSourceFile*)this",
+                       yytext,
+               );
+               perUserDictionary = {
+                       "PBXConfiguration.PBXBreakpointsDataSource.v1:1CA1AED706398EBD00589147" = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_LocationID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       20,
+                                       210,
+                                       20,
+                                       138,
+                                       81,
+                                       20,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXBreakpointsDataSource_ActionID,
+                                       PBXBreakpointsDataSource_TypeID,
+                                       PBXBreakpointsDataSource_BreakpointID,
+                                       PBXBreakpointsDataSource_UseID,
+                                       PBXBreakpointsDataSource_LocationID,
+                                       PBXBreakpointsDataSource_ConditionID,
+                                       PBXBreakpointsDataSource_ContinueID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       578,
+                                       126,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXErrorsWarningsDataSource_TypeID,
+                                       PBXErrorsWarningsDataSource_MessageID,
+                                       PBXErrorsWarningsDataSource_LocationID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       22,
+                                       300,
+                                       402,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXExecutablesDataSource_ActiveFlagID,
+                                       PBXExecutablesDataSource_NameID,
+                                       PBXExecutablesDataSource_CommentsID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       632,
+                                       20,
+                                       48,
+                                       43,
+                                       43,
+                                       20,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXFileDataSource_FiletypeID,
+                                       PBXFileDataSource_Filename_ColumnID,
+                                       PBXFileDataSource_Built_ColumnID,
+                                       PBXFileDataSource_ObjectSize_ColumnID,
+                                       PBXFileDataSource_Errors_ColumnID,
+                                       PBXFileDataSource_Warnings_ColumnID,
+                                       PBXFileDataSource_Target_ColumnID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       575,
+                                       157,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXFindDataSource_MessageID,
+                                       PBXFindDataSource_LocationID,
+                               );
+                       };
+                       PBXConfiguration.PBXFileTableDataSource3.XCSCMDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       20,
+                                       524,
+                                       20,
+                                       48.1626,
+                                       43,
+                                       43,
+                                       20,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXFileDataSource_SCM_ColumnID,
+                                       PBXFileDataSource_FiletypeID,
+                                       PBXFileDataSource_Filename_ColumnID,
+                                       PBXFileDataSource_Built_ColumnID,
+                                       PBXFileDataSource_ObjectSize_ColumnID,
+                                       PBXFileDataSource_Errors_ColumnID,
+                                       PBXFileDataSource_Warnings_ColumnID,
+                                       PBXFileDataSource_Target_ColumnID,
+                               );
+                       };
+                       PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+                               PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+                               PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+                               PBXFileTableDataSourceColumnWidthsKey = (
+                                       20,
+                                       200,
+                                       360,
+                                       20,
+                                       48,
+                                       43,
+                                       43,
+                               );
+                               PBXFileTableDataSourceColumnsKey = (
+                                       PBXFileDataSource_FiletypeID,
+                                       PBXFileDataSource_Filename_ColumnID,
+                                       PBXTargetDataSource_PrimaryAttribute,
+                                       PBXFileDataSource_Built_ColumnID,
+                                       PBXFileDataSource_ObjectSize_ColumnID,
+                                       PBXFileDataSource_Errors_ColumnID,
+                                       PBXFileDataSource_Warnings_ColumnID,
+                               );
+                       };
+                       PBXPerProjectTemplateStateSaveDate = 303262107;
+                       PBXWorkspaceStateSaveDate = 303262107;
+               };
+               perUserProjectItems = {
+                       021CA4400A8D2F740028326F = 021CA4400A8D2F740028326F /* PBXTextBookmark */;
+                       021CA4420A8D2F740028326F = 021CA4420A8D2F740028326F /* PBXTextBookmark */;
+                       022B461212136A6A00A74F96 /* PBXTextBookmark */ = 022B461212136A6A00A74F96 /* PBXTextBookmark */;
+                       022B461312136A6A00A74F96 /* XCBuildMessageTextBookmark */ = 022B461312136A6A00A74F96 /* XCBuildMessageTextBookmark */;
+                       022B461412136A6A00A74F96 /* PBXTextBookmark */ = 022B461412136A6A00A74F96 /* PBXTextBookmark */;
+                       022B46161216FE9C00A74F96 /* PBXTextBookmark */ = 022B46161216FE9C00A74F96 /* PBXTextBookmark */;
+                       022B46181216FE9C00A74F96 /* PBXTextBookmark */ = 022B46181216FE9C00A74F96 /* PBXTextBookmark */;
+                       022B46191216FE9C00A74F96 /* PBXTextBookmark */ = 022B46191216FE9C00A74F96 /* PBXTextBookmark */;
+                       022B461A1216FE9C00A74F96 /* PBXTextBookmark */ = 022B461A1216FE9C00A74F96 /* PBXTextBookmark */;
+                       022B461D1216FEA700A74F96 /* PBXTextBookmark */ = 022B461D1216FEA700A74F96 /* PBXTextBookmark */;
+                       022B461E1216FEA700A74F96 /* PBXTextBookmark */ = 022B461E1216FEA700A74F96 /* PBXTextBookmark */;
+                       022B461F1216FEA700A74F96 /* PBXTextBookmark */ = 022B461F1216FEA700A74F96 /* PBXTextBookmark */;
+                       022B46201216FEA700A74F96 /* PBXTextBookmark */ = 022B46201216FEA700A74F96 /* PBXTextBookmark */;
+                       022B46211216FEA700A74F96 /* PBXTextBookmark */ = 022B46211216FEA700A74F96 /* PBXTextBookmark */;
+                       022B46221216FEA700A74F96 /* PBXTextBookmark */ = 022B46221216FEA700A74F96 /* PBXTextBookmark */;
+                       022B46231216FEA700A74F96 /* PBXTextBookmark */ = 022B46231216FEA700A74F96 /* PBXTextBookmark */;
+                       022B46241216FEA700A74F96 /* PBXTextBookmark */ = 022B46241216FEA700A74F96 /* PBXTextBookmark */;
+                       022B46251216FEA700A74F96 /* PBXTextBookmark */ = 022B46251216FEA700A74F96 /* PBXTextBookmark */;
+                       022B4632121700F300A74F96 /* PBXTextBookmark */ = 022B4632121700F300A74F96 /* PBXTextBookmark */;
+                       022B4639121700F300A74F96 /* PBXTextBookmark */ = 022B4639121700F300A74F96 /* PBXTextBookmark */;
+                       022B464E1217576E00A74F96 /* PBXTextBookmark */ = 022B464E1217576E00A74F96 /* PBXTextBookmark */;
+                       022B464F1217576E00A74F96 /* PBXTextBookmark */ = 022B464F1217576E00A74F96 /* PBXTextBookmark */;
+                       022B46501217576E00A74F96 /* PBXTextBookmark */ = 022B46501217576E00A74F96 /* PBXTextBookmark */;
+                       022B46511217576E00A74F96 /* PBXTextBookmark */ = 022B46511217576E00A74F96 /* PBXTextBookmark */;
+                       022B46521217576E00A74F96 /* PBXTextBookmark */ = 022B46521217576E00A74F96 /* PBXTextBookmark */;
+                       022B46531217576E00A74F96 /* PBXTextBookmark */ = 022B46531217576E00A74F96 /* PBXTextBookmark */;
+                       022B46541217576E00A74F96 /* PBXTextBookmark */ = 022B46541217576E00A74F96 /* PBXTextBookmark */;
+                       022B46601218557900A74F96 /* PBXTextBookmark */ = 022B46601218557900A74F96 /* PBXTextBookmark */;
+                       022B46611218557900A74F96 /* PBXTextBookmark */ = 022B46611218557900A74F96 /* PBXTextBookmark */;
+                       022B466412185DA400A74F96 /* PBXTextBookmark */ = 022B466412185DA400A74F96 /* PBXTextBookmark */;
+                       022B466512185DA400A74F96 /* PBXTextBookmark */ = 022B466512185DA400A74F96 /* PBXTextBookmark */;
+                       022B466C12185F4800A74F96 /* PBXTextBookmark */ = 022B466C12185F4800A74F96 /* PBXTextBookmark */;
+                       022B466D12185F4800A74F96 /* PBXTextBookmark */ = 022B466D12185F4800A74F96 /* PBXTextBookmark */;
+                       022B46701218625A00A74F96 /* PBXTextBookmark */ = 022B46701218625A00A74F96 /* PBXTextBookmark */;
+                       022B46711218625A00A74F96 /* PBXTextBookmark */ = 022B46711218625A00A74F96 /* PBXTextBookmark */;
+                       022B4678121864A000A74F96 /* PBXTextBookmark */ = 022B4678121864A000A74F96 /* PBXTextBookmark */;
+                       022B4679121864A000A74F96 /* XCBuildMessageTextBookmark */ = 022B4679121864A000A74F96 /* XCBuildMessageTextBookmark */;
+                       022B467A121864A000A74F96 /* PBXTextBookmark */ = 022B467A121864A000A74F96 /* PBXTextBookmark */;
+                       022B467B121864A000A74F96 /* PBXTextBookmark */ = 022B467B121864A000A74F96 /* PBXTextBookmark */;
+                       022B46801218654500A74F96 /* PBXTextBookmark */ = 022B46801218654500A74F96 /* PBXTextBookmark */;
+                       022B46811218654500A74F96 /* PBXTextBookmark */ = 022B46811218654500A74F96 /* PBXTextBookmark */;
+                       022B46871218659100A74F96 /* PBXTextBookmark */ = 022B46871218659100A74F96 /* PBXTextBookmark */;
+                       022B46881218659100A74F96 /* PBXTextBookmark */ = 022B46881218659100A74F96 /* PBXTextBookmark */;
+                       022B46891218659A00A74F96 /* PBXTextBookmark */ = 022B46891218659A00A74F96 /* PBXTextBookmark */;
+                       022B468A1218659A00A74F96 /* PBXTextBookmark */ = 022B468A1218659A00A74F96 /* PBXTextBookmark */;
+                       022B468B1218659A00A74F96 /* PBXTextBookmark */ = 022B468B1218659A00A74F96 /* PBXTextBookmark */;
+                       022B468C1218659A00A74F96 /* PBXTextBookmark */ = 022B468C1218659A00A74F96 /* PBXTextBookmark */;
+                       022B468D1218659A00A74F96 /* PBXTextBookmark */ = 022B468D1218659A00A74F96 /* PBXTextBookmark */;
+                       022B468E1218659A00A74F96 /* PBXTextBookmark */ = 022B468E1218659A00A74F96 /* PBXTextBookmark */;
+                       022B468F1218659A00A74F96 /* PBXTextBookmark */ = 022B468F1218659A00A74F96 /* PBXTextBookmark */;
+                       022B46901218659A00A74F96 /* PBXTextBookmark */ = 022B46901218659A00A74F96 /* PBXTextBookmark */;
+                       022B46911218659A00A74F96 /* PBXTextBookmark */ = 022B46911218659A00A74F96 /* PBXTextBookmark */;
+                       022B46921218659A00A74F96 /* PBXTextBookmark */ = 022B46921218659A00A74F96 /* PBXTextBookmark */;
+                       022B46931218659A00A74F96 /* PBXTextBookmark */ = 022B46931218659A00A74F96 /* PBXTextBookmark */;
+                       022B46941218659A00A74F96 /* PBXTextBookmark */ = 022B46941218659A00A74F96 /* PBXTextBookmark */;
+                       022B46951218659A00A74F96 /* PBXTextBookmark */ = 022B46951218659A00A74F96 /* PBXTextBookmark */;
+                       022B46961218659A00A74F96 /* PBXTextBookmark */ = 022B46961218659A00A74F96 /* PBXTextBookmark */;
+                       022B46971218659A00A74F96 /* PBXTextBookmark */ = 022B46971218659A00A74F96 /* PBXTextBookmark */;
+                       022B469D121865E000A74F96 /* PBXTextBookmark */ = 022B469D121865E000A74F96 /* PBXTextBookmark */;
+                       022B469E121865E000A74F96 /* PBXTextBookmark */ = 022B469E121865E000A74F96 /* PBXTextBookmark */;
+                       022B46A1121865E300A74F96 /* PBXTextBookmark */ = 022B46A1121865E300A74F96 /* PBXTextBookmark */;
+                       022B46A2121865E300A74F96 /* PBXTextBookmark */ = 022B46A2121865E300A74F96 /* PBXTextBookmark */;
+                       022B46A5121865F700A74F96 /* PBXTextBookmark */ = 022B46A5121865F700A74F96 /* PBXTextBookmark */;
+                       022B46A6121865F700A74F96 /* PBXTextBookmark */ = 022B46A6121865F700A74F96 /* PBXTextBookmark */;
+                       022B46A91218660A00A74F96 /* PBXTextBookmark */ = 022B46A91218660A00A74F96 /* PBXTextBookmark */;
+                       022B46AA1218660A00A74F96 /* PBXTextBookmark */ = 022B46AA1218660A00A74F96 /* PBXTextBookmark */;
+                       022B46AD1218662100A74F96 /* PBXTextBookmark */ = 022B46AD1218662100A74F96 /* PBXTextBookmark */;
+                       022B46AE1218662100A74F96 /* PBXTextBookmark */ = 022B46AE1218662100A74F96 /* PBXTextBookmark */;
+                       022B46B11218662D00A74F96 /* PBXTextBookmark */ = 022B46B11218662D00A74F96 /* PBXTextBookmark */;
+                       022B46B21218662D00A74F96 /* PBXTextBookmark */ = 022B46B21218662D00A74F96 /* PBXTextBookmark */;
+                       022B46B31218663500A74F96 /* PBXTextBookmark */ = 022B46B31218663500A74F96 /* PBXTextBookmark */;
+                       022B46B71218665300A74F96 /* PBXTextBookmark */ = 022B46B71218665300A74F96 /* PBXTextBookmark */;
+                       022B46B81218665300A74F96 /* PBXTextBookmark */ = 022B46B81218665300A74F96 /* PBXTextBookmark */;
+                       022B46B91218665600A74F96 /* PBXTextBookmark */ = 022B46B91218665600A74F96 /* PBXTextBookmark */;
+                       022B46BD1218667B00A74F96 /* PBXTextBookmark */ = 022B46BD1218667B00A74F96 /* PBXTextBookmark */;
+                       022B46BE1218667B00A74F96 /* PBXTextBookmark */ = 022B46BE1218667B00A74F96 /* PBXTextBookmark */;
+                       022B46C11218673300A74F96 /* PBXTextBookmark */ = 022B46C11218673300A74F96 /* PBXTextBookmark */;
+                       022B46C21218673300A74F96 /* PBXTextBookmark */ = 022B46C21218673300A74F96 /* PBXTextBookmark */;
+                       022B46C3121867D800A74F96 /* PBXTextBookmark */ = 022B46C3121867D800A74F96 /* PBXTextBookmark */;
+                       022B46C61218685B00A74F96 /* PBXTextBookmark */ = 022B46C61218685B00A74F96 /* PBXTextBookmark */;
+                       022B46C71218685B00A74F96 /* PBXTextBookmark */ = 022B46C71218685B00A74F96 /* PBXTextBookmark */;
+                       022B46C81218686300A74F96 /* PBXTextBookmark */ = 022B46C81218686300A74F96 /* PBXTextBookmark */;
+                       022B46CC1218687300A74F96 /* PBXTextBookmark */ = 022B46CC1218687300A74F96 /* PBXTextBookmark */;
+                       022B46CD1218687300A74F96 /* PBXTextBookmark */ = 022B46CD1218687300A74F96 /* PBXTextBookmark */;
+                       022B46CE1218687700A74F96 /* PBXTextBookmark */ = 022B46CE1218687700A74F96 /* PBXTextBookmark */;
+                       022B46D1121868F200A74F96 /* PBXTextBookmark */ = 022B46D1121868F200A74F96 /* PBXTextBookmark */;
+                       022B46D2121868F200A74F96 /* PBXTextBookmark */ = 022B46D2121868F200A74F96 /* PBXTextBookmark */;
+                       022B46D3121868FD00A74F96 /* PBXTextBookmark */ = 022B46D3121868FD00A74F96 /* PBXTextBookmark */;
+                       022B46D4121868FD00A74F96 /* PBXTextBookmark */ = 022B46D4121868FD00A74F96 /* PBXTextBookmark */;
+                       022B46D5121868FD00A74F96 /* PBXTextBookmark */ = 022B46D5121868FD00A74F96 /* PBXTextBookmark */;
+                       022B46D81218690400A74F96 /* PBXTextBookmark */ = 022B46D81218690400A74F96 /* PBXTextBookmark */;
+                       022B46D91218690400A74F96 /* PBXTextBookmark */ = 022B46D91218690400A74F96 /* PBXTextBookmark */;
+                       022B46DC1218694400A74F96 /* PBXTextBookmark */ = 022B46DC1218694400A74F96 /* PBXTextBookmark */;
+                       022B46DD1218694400A74F96 /* PBXTextBookmark */ = 022B46DD1218694400A74F96 /* PBXTextBookmark */;
+                       022B46DE1218694900A74F96 /* PBXTextBookmark */ = 022B46DE1218694900A74F96 /* PBXTextBookmark */;
+                       022B46E11218696F00A74F96 /* PBXTextBookmark */ = 022B46E11218696F00A74F96 /* PBXTextBookmark */;
+                       022B46E21218696F00A74F96 /* PBXTextBookmark */ = 022B46E21218696F00A74F96 /* PBXTextBookmark */;
+                       022B46E31218697600A74F96 /* PBXTextBookmark */ = 022B46E31218697600A74F96 /* PBXTextBookmark */;
+                       022B46E61218699C00A74F96 /* PBXTextBookmark */ = 022B46E61218699C00A74F96 /* PBXTextBookmark */;
+                       022B46E71218699C00A74F96 /* PBXTextBookmark */ = 022B46E71218699C00A74F96 /* PBXTextBookmark */;
+                       022B46E8121869A100A74F96 /* PBXTextBookmark */ = 022B46E8121869A100A74F96 /* PBXTextBookmark */;
+                       022B46EC12186A4400A74F96 /* PBXTextBookmark */ = 022B46EC12186A4400A74F96 /* PBXTextBookmark */;
+                       022B46ED12186A4400A74F96 /* PBXTextBookmark */ = 022B46ED12186A4400A74F96 /* PBXTextBookmark */;
+                       022B46EE12186A5B00A74F96 /* PBXTextBookmark */ = 022B46EE12186A5B00A74F96 /* PBXTextBookmark */;
+                       022B46F112186A6700A74F96 /* PBXTextBookmark */ = 022B46F112186A6700A74F96 /* PBXTextBookmark */;
+                       022B46F212186A6700A74F96 /* PBXTextBookmark */ = 022B46F212186A6700A74F96 /* PBXTextBookmark */;
+                       022B46F312186A8300A74F96 /* PBXTextBookmark */ = 022B46F312186A8300A74F96 /* PBXTextBookmark */;
+                       022B46F612186AFC00A74F96 /* PBXTextBookmark */ = 022B46F612186AFC00A74F96 /* PBXTextBookmark */;
+                       022B46F712186AFC00A74F96 /* PBXTextBookmark */ = 022B46F712186AFC00A74F96 /* PBXTextBookmark */;
+                       022B46FA1218B7B300A74F96 /* PBXTextBookmark */ = 022B46FA1218B7B300A74F96 /* PBXTextBookmark */;
+                       022B46FB1218B7B300A74F96 /* PBXTextBookmark */ = 022B46FB1218B7B300A74F96 /* PBXTextBookmark */;
+                       022B46FE1218B7F600A74F96 /* PBXTextBookmark */ = 022B46FE1218B7F600A74F96 /* PBXTextBookmark */;
+                       022B46FF1218B7F600A74F96 /* PBXTextBookmark */ = 022B46FF1218B7F600A74F96 /* PBXTextBookmark */;
+                       022B47021218B95800A74F96 /* PBXTextBookmark */ = 022B47021218B95800A74F96 /* PBXTextBookmark */;
+                       022B47031218B95800A74F96 /* PBXTextBookmark */ = 022B47031218B95800A74F96 /* PBXTextBookmark */;
+                       022B47041218B95D00A74F96 /* PBXTextBookmark */ = 022B47041218B95D00A74F96 /* PBXTextBookmark */;
+                       022B47051218B95D00A74F96 /* PBXTextBookmark */ = 022B47051218B95D00A74F96 /* PBXTextBookmark */;
+                       022B47061218B95D00A74F96 /* PBXTextBookmark */ = 022B47061218B95D00A74F96 /* PBXTextBookmark */;
+                       022B47091218B96300A74F96 /* PBXTextBookmark */ = 022B47091218B96300A74F96 /* PBXTextBookmark */;
+                       022B470A1218B96300A74F96 /* PBXTextBookmark */ = 022B470A1218B96300A74F96 /* PBXTextBookmark */;
+                       022B470D1218B99F00A74F96 /* PBXTextBookmark */ = 022B470D1218B99F00A74F96 /* PBXTextBookmark */;
+                       022B470E1218B99F00A74F96 /* PBXTextBookmark */ = 022B470E1218B99F00A74F96 /* PBXTextBookmark */;
+                       022B470F1218B9AF00A74F96 /* PBXTextBookmark */ = 022B470F1218B9AF00A74F96 /* PBXTextBookmark */;
+                       022B47121218B9B300A74F96 /* PBXTextBookmark */ = 022B47121218B9B300A74F96 /* PBXTextBookmark */;
+                       022B47131218B9B300A74F96 /* PBXTextBookmark */ = 022B47131218B9B300A74F96 /* PBXTextBookmark */;
+                       022B47161218C00000A74F96 /* PBXTextBookmark */ = 022B47161218C00000A74F96 /* PBXTextBookmark */;
+                       022B47171218C00000A74F96 /* PBXTextBookmark */ = 022B47171218C00000A74F96 /* PBXTextBookmark */;
+                       022B47181218C00400A74F96 /* PBXTextBookmark */ = 022B47181218C00400A74F96 /* PBXTextBookmark */;
+                       022B471B1218C00E00A74F96 /* PBXTextBookmark */ = 022B471B1218C00E00A74F96 /* PBXTextBookmark */;
+                       022B471C1218C00E00A74F96 /* PBXTextBookmark */ = 022B471C1218C00E00A74F96 /* PBXTextBookmark */;
+                       022B471D1218C01000A74F96 /* PBXTextBookmark */ = 022B471D1218C01000A74F96 /* PBXTextBookmark */;
+                       022B47201218C12800A74F96 /* PBXTextBookmark */ = 022B47201218C12800A74F96 /* PBXTextBookmark */;
+                       022B47211218C12800A74F96 /* PBXTextBookmark */ = 022B47211218C12800A74F96 /* PBXTextBookmark */;
+                       022B47221218C13000A74F96 /* PBXTextBookmark */ = 022B47221218C13000A74F96 /* PBXTextBookmark */;
+                       022B47261218C17D00A74F96 /* PBXTextBookmark */ = 022B47261218C17D00A74F96 /* PBXTextBookmark */;
+                       022B47271218C17D00A74F96 /* PBXTextBookmark */ = 022B47271218C17D00A74F96 /* PBXTextBookmark */;
+                       022B47281218C17F00A74F96 /* PBXTextBookmark */ = 022B47281218C17F00A74F96 /* PBXTextBookmark */;
+                       022B47291218C17F00A74F96 /* PBXTextBookmark */ = 022B47291218C17F00A74F96 /* PBXTextBookmark */;
+                       022B472A1218C17F00A74F96 /* PBXTextBookmark */ = 022B472A1218C17F00A74F96 /* PBXTextBookmark */;
+                       022B472D1218C18600A74F96 /* PBXTextBookmark */ = 022B472D1218C18600A74F96 /* PBXTextBookmark */;
+                       022B472E1218C18600A74F96 /* PBXTextBookmark */ = 022B472E1218C18600A74F96 /* PBXTextBookmark */;
+                       022B472F1218C19000A74F96 /* PBXTextBookmark */ = 022B472F1218C19000A74F96 /* PBXTextBookmark */;
+                       022B47351218C46700A74F96 /* PBXTextBookmark */ = 022B47351218C46700A74F96 /* PBXTextBookmark */;
+                       022B47361218C46700A74F96 /* XCBuildMessageTextBookmark */ = 022B47361218C46700A74F96 /* XCBuildMessageTextBookmark */;
+                       022B47371218C46700A74F96 /* PBXTextBookmark */ = 022B47371218C46700A74F96 /* PBXTextBookmark */;
+                       022B47381218C46700A74F96 /* PBXTextBookmark */ = 022B47381218C46700A74F96 /* PBXTextBookmark */;
+                       022B47391218C46A00A74F96 /* PBXTextBookmark */ = 022B47391218C46A00A74F96 /* PBXTextBookmark */;
+                       022B473A1218C46A00A74F96 /* PBXTextBookmark */ = 022B473A1218C46A00A74F96 /* PBXTextBookmark */;
+                       022B473B1218C46A00A74F96 /* PBXTextBookmark */ = 022B473B1218C46A00A74F96 /* PBXTextBookmark */;
+                       022B473C1218C46A00A74F96 /* PBXTextBookmark */ = 022B473C1218C46A00A74F96 /* PBXTextBookmark */;
+                       022B473F1218C46E00A74F96 /* PBXTextBookmark */ = 022B473F1218C46E00A74F96 /* PBXTextBookmark */;
+                       022B47401218C46E00A74F96 /* PBXTextBookmark */ = 022B47401218C46E00A74F96 /* PBXTextBookmark */;
+                       022B47411218C47C00A74F96 /* PBXTextBookmark */ = 022B47411218C47C00A74F96 /* PBXTextBookmark */;
+                       022B47451218C49900A74F96 /* PBXTextBookmark */ = 022B47451218C49900A74F96 /* PBXTextBookmark */;
+                       022B47461218C49900A74F96 /* PBXTextBookmark */ = 022B47461218C49900A74F96 /* PBXTextBookmark */;
+                       022B47491218CA9900A74F96 /* PBXTextBookmark */ = 022B47491218CA9900A74F96 /* PBXTextBookmark */;
+                       022B474A1218CA9900A74F96 /* PBXTextBookmark */ = 022B474A1218CA9900A74F96 /* PBXTextBookmark */;
+                       022B474B1218CA9A00A74F96 /* PBXTextBookmark */ = 022B474B1218CA9A00A74F96 /* PBXTextBookmark */;
+                       022B474C1218CA9A00A74F96 /* PBXTextBookmark */ = 022B474C1218CA9A00A74F96 /* PBXTextBookmark */;
+                       022B474D1218CA9A00A74F96 /* PBXTextBookmark */ = 022B474D1218CA9A00A74F96 /* PBXTextBookmark */;
+                       022B474E1218CA9A00A74F96 /* PBXTextBookmark */ = 022B474E1218CA9A00A74F96 /* PBXTextBookmark */;
+                       022B47511218CAA200A74F96 /* PBXTextBookmark */ = 022B47511218CAA200A74F96 /* PBXTextBookmark */;
+                       022B47521218CAA200A74F96 /* PBXTextBookmark */ = 022B47521218CAA200A74F96 /* PBXTextBookmark */;
+                       022B47531218CAAA00A74F96 /* PBXTextBookmark */ = 022B47531218CAAA00A74F96 /* PBXTextBookmark */;
+                       022B47571218CACE00A74F96 /* PBXTextBookmark */ = 022B47571218CACE00A74F96 /* PBXTextBookmark */;
+                       022B47581218CACE00A74F96 /* PBXTextBookmark */ = 022B47581218CACE00A74F96 /* PBXTextBookmark */;
+                       022B475B1218CAD200A74F96 /* PBXTextBookmark */ = 022B475B1218CAD200A74F96 /* PBXTextBookmark */;
+                       022B475C1218CAD200A74F96 /* PBXTextBookmark */ = 022B475C1218CAD200A74F96 /* PBXTextBookmark */;
+                       022B475D1218CAD700A74F96 /* PBXTextBookmark */ = 022B475D1218CAD700A74F96 /* PBXTextBookmark */;
+                       022B47601218CADD00A74F96 /* PBXTextBookmark */ = 022B47601218CADD00A74F96 /* PBXTextBookmark */;
+                       022B47611218CADD00A74F96 /* PBXTextBookmark */ = 022B47611218CADD00A74F96 /* PBXTextBookmark */;
+                       022B47621218CAE000A74F96 /* PBXTextBookmark */ = 022B47621218CAE000A74F96 /* PBXTextBookmark */;
+                       022B47651218CDA800A74F96 /* PBXTextBookmark */ = 022B47651218CDA800A74F96 /* PBXTextBookmark */;
+                       022B47661218CDA800A74F96 /* PBXTextBookmark */ = 022B47661218CDA800A74F96 /* PBXTextBookmark */;
+                       022B47691218CDAE00A74F96 /* PBXTextBookmark */ = 022B47691218CDAE00A74F96 /* PBXTextBookmark */;
+                       022B476A1218CDAE00A74F96 /* PBXTextBookmark */ = 022B476A1218CDAE00A74F96 /* PBXTextBookmark */;
+                       022B476D1218CDBB00A74F96 /* PBXTextBookmark */ = 022B476D1218CDBB00A74F96 /* PBXTextBookmark */;
+                       022B476E1218CDBB00A74F96 /* PBXTextBookmark */ = 022B476E1218CDBB00A74F96 /* PBXTextBookmark */;
+                       022B476F1218CDBF00A74F96 /* PBXTextBookmark */ = 022B476F1218CDBF00A74F96 /* PBXTextBookmark */;
+                       022B47701218CDBF00A74F96 /* PBXTextBookmark */ = 022B47701218CDBF00A74F96 /* PBXTextBookmark */;
+                       022B47711218CDBF00A74F96 /* PBXTextBookmark */ = 022B47711218CDBF00A74F96 /* PBXTextBookmark */;
+                       022B47721218CDBF00A74F96 /* PBXTextBookmark */ = 022B47721218CDBF00A74F96 /* PBXTextBookmark */;
+                       0234AF900D69029300A16BFF = 0234AF900D69029300A16BFF /* PBXTextBookmark */;
+                       0234AF910D69029300A16BFF = 0234AF910D69029300A16BFF /* PBXTextBookmark */;
+                       0234AF920D69029300A16BFF = 0234AF920D69029300A16BFF /* PBXTextBookmark */;
+                       0234AF930D69029300A16BFF = 0234AF930D69029300A16BFF /* PBXTextBookmark */;
+                       0234AF950D69029300A16BFF = 0234AF950D69029300A16BFF /* PBXTextBookmark */;
+                       0234AF970D69029300A16BFF = 0234AF970D69029300A16BFF /* PBXTextBookmark */;
+                       0234AF9A0D69029300A16BFF = 0234AF9A0D69029300A16BFF /* PBXTextBookmark */;
+                       0234AF9C0D69029300A16BFF = 0234AF9C0D69029300A16BFF /* PBXTextBookmark */;
+                       0234AF9D0D69029300A16BFF = 0234AF9D0D69029300A16BFF /* PBXTextBookmark */;
+                       0234AFA00D69029300A16BFF = 0234AFA00D69029300A16BFF /* PBXTextBookmark */;
+                       0234AFA20D69029300A16BFF = 0234AFA20D69029300A16BFF /* PBXTextBookmark */;
+                       024A0F200C53B9D8000317D4 = 024A0F200C53B9D8000317D4 /* PBXTextBookmark */;
+                       0258817C0CF13C0400681C7E = 0258817C0CF13C0400681C7E /* PBXTextBookmark */;
+                       025881810CF13C0400681C7E = 025881810CF13C0400681C7E /* PBXTextBookmark */;
+                       025881850CF13C0400681C7E = 025881850CF13C0400681C7E /* PBXTextBookmark */;
+                       025881860CF13C0400681C7E = 025881860CF13C0400681C7E /* PBXTextBookmark */;
+                       025881870CF13C0400681C7E = 025881870CF13C0400681C7E /* PBXTextBookmark */;
+                       025881890CF13C0400681C7E = 025881890CF13C0400681C7E /* PBXTextBookmark */;
+                       027EE3C30BD6930A00A6A136 = 027EE3C30BD6930A00A6A136 /* PBXTextBookmark */;
+                       027EE3C80BD6930A00A6A136 = 027EE3C80BD6930A00A6A136 /* PBXTextBookmark */;
+                       0292B60E0CDA9CFD00A3A500 = 0292B60E0CDA9CFD00A3A500 /* PBXTextBookmark */;
+                       0292B60F0CDA9CFD00A3A500 = 0292B60F0CDA9CFD00A3A500 /* PBXTextBookmark */;
+                       0292B6100CDA9CFD00A3A500 = 0292B6100CDA9CFD00A3A500 /* PBXTextBookmark */;
+                       0292B6160CDA9CFD00A3A500 = 0292B6160CDA9CFD00A3A500 /* PBXTextBookmark */;
+                       0292B6170CDA9CFD00A3A500 = 0292B6170CDA9CFD00A3A500 /* PBXTextBookmark */;
+                       0292B6180CDA9CFD00A3A500 = 0292B6180CDA9CFD00A3A500 /* PBXTextBookmark */;
+                       02C5DBD20A926A7F003B9C11 = 02C5DBD20A926A7F003B9C11 /* PBXTextBookmark */;
+                       02C5DBDB0A926A7F003B9C11 = 02C5DBDB0A926A7F003B9C11 /* PBXTextBookmark */;
+                       02C5DC310A93C14E003B9C11 = 02C5DC310A93C14E003B9C11 /* PBXTextBookmark */;
+                       02C5DC330A93C14E003B9C11 = 02C5DC330A93C14E003B9C11 /* PBXTextBookmark */;
+                       02C5DC350A93C14E003B9C11 = 02C5DC350A93C14E003B9C11 /* PBXTextBookmark */;
+                       02C5DCB50A93CA0A003B9C11 = 02C5DCB50A93CA0A003B9C11 /* PBXTextBookmark */;
+                       02C5DD520A93D327003B9C11 = 02C5DD520A93D327003B9C11 /* PBXTextBookmark */;
+                       02C5DDCD0A940126003B9C11 = 02C5DDCD0A940126003B9C11 /* PBXTextBookmark */;
+                       02C5DDCF0A940126003B9C11 = 02C5DDCF0A940126003B9C11 /* PBXTextBookmark */;
+                       02CAC9BA0BA06EA50020B29B = 02CAC9BA0BA06EA50020B29B /* PBXTextBookmark */;
+                       02D1FD190BD039BF007C7450 = 02D1FD190BD039BF007C7450 /* PBXTextBookmark */;
+                       02D1FE2E0BD1505E007C7450 = 02D1FE2E0BD1505E007C7450 /* PBXTextBookmark */;
+                       02D46C3B0FED5C3600E65706 = 02D46C3B0FED5C3600E65706 /* PBXTextBookmark */;
+                       02D46C3F0FED5C3600E65706 = 02D46C3F0FED5C3600E65706 /* PBXTextBookmark */;
+                       02D46C690FED5F4B00E65706 = 02D46C690FED5F4B00E65706 /* PBXTextBookmark */;
+                       02D46D1A0FED80BF00E65706 = 02D46D1A0FED80BF00E65706 /* PBXTextBookmark */;
+                       02D6132E10F28A6500B7DF2F = 02D6132E10F28A6500B7DF2F /* PBXTextBookmark */;
+                       02D6132F10F28A6500B7DF2F = 02D6132F10F28A6500B7DF2F /* PBXTextBookmark */;
+                       02D6133010F28A6500B7DF2F = 02D6133010F28A6500B7DF2F /* PBXTextBookmark */;
+                       02D6138C10F3E89000B7DF2F = 02D6138C10F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6138D10F3E89000B7DF2F = 02D6138D10F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6138E10F3E89000B7DF2F = 02D6138E10F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6138F10F3E89000B7DF2F = 02D6138F10F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139010F3E89000B7DF2F = 02D6139010F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139110F3E89000B7DF2F = 02D6139110F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139210F3E89000B7DF2F = 02D6139210F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139310F3E89000B7DF2F = 02D6139310F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139410F3E89000B7DF2F = 02D6139410F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139510F3E89000B7DF2F = 02D6139510F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139610F3E89000B7DF2F = 02D6139610F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139710F3E89000B7DF2F = 02D6139710F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139810F3E89000B7DF2F = 02D6139810F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139910F3E89000B7DF2F = 02D6139910F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139B10F3E89000B7DF2F = 02D6139B10F3E89000B7DF2F /* PBXTextBookmark */;
+                       02D6139F10F3E96300B7DF2F = 02D6139F10F3E96300B7DF2F /* PBXTextBookmark */;
+                       02D795420FF00D8B00C1C5DF = 02D795420FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D795430FF00D8B00C1C5DF = 02D795430FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D795440FF00D8B00C1C5DF = 02D795440FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D795450FF00D8B00C1C5DF = 02D795450FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D795460FF00D8B00C1C5DF = 02D795460FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D795470FF00D8B00C1C5DF = 02D795470FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D795480FF00D8B00C1C5DF = 02D795480FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D795490FF00D8B00C1C5DF = 02D795490FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D7954A0FF00D8B00C1C5DF = 02D7954A0FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02D7954D0FF00D8B00C1C5DF = 02D7954D0FF00D8B00C1C5DF /* PBXTextBookmark */;
+                       02E535CF0C24641A00CBD4A5 = 02E535CF0C24641A00CBD4A5 /* PBXTextBookmark */;
+                       02E535D00C24641A00CBD4A5 = 02E535D00C24641A00CBD4A5 /* PBXTextBookmark */;
+                       02E535D20C24641A00CBD4A5 = 02E535D20C24641A00CBD4A5 /* PBXTextBookmark */;
+                       02E535D40C24641A00CBD4A5 = 02E535D40C24641A00CBD4A5 /* PBXTextBookmark */;
+                       02E535D70C24641A00CBD4A5 = 02E535D70C24641A00CBD4A5 /* PBXTextBookmark */;
+                       02E535D90C24641A00CBD4A5 = 02E535D90C24641A00CBD4A5 /* PBXTextBookmark */;
+                       02E535F10C24641A00CBD4A5 = 02E535F10C24641A00CBD4A5 /* PBXTextBookmark */;
+                       02E5362D0C38763700CBD4A5 = 02E5362D0C38763700CBD4A5 /* PBXTextBookmark */;
+                       02E536320C38763700CBD4A5 = 02E536320C38763700CBD4A5 /* PBXTextBookmark */;
+                       02E536340C38763700CBD4A5 = 02E536340C38763700CBD4A5 /* PBXTextBookmark */;
+                       02E536350C38763700CBD4A5 = 02E536350C38763700CBD4A5 /* PBXTextBookmark */;
+                       02E536360C38763700CBD4A5 = 02E536360C38763700CBD4A5 /* PBXTextBookmark */;
+                       02E5363F0C3C4FF000CBD4A5 = 02E5363F0C3C4FF000CBD4A5 /* PBXTextBookmark */;
+                       02FE651B0BFF94B2004A1450 = 02FE651B0BFF94B2004A1450 /* PBXTextBookmark */;
+               };
+               sourceControlManager = 0296A50409D9AE9400F80AFF /* Source Control */;
+               userBuildSettings = {
+               };
+       };
+       8DD76F620486A84900D96B5E /* elftosb */ = {
+               activeExec = 0;
+               executables = (
+                       0296A45509D9AE7A00F80AFF /* elftosb */,
+               );
+       };
+}
diff --git a/tools/elftosb/elftosb.xcodeproj/project.pbxproj b/tools/elftosb/elftosb.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..85ab788
--- /dev/null
@@ -0,0 +1,943 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 45;
+       objects = {
+
+/* Begin PBXAggregateTarget section */
+               020DDCE80A1E858600E1CB49 /* Everything */ = {
+                       isa = PBXAggregateTarget;
+                       buildConfigurationList = 020DDCF00A1E85BA00E1CB49 /* Build configuration list for PBXAggregateTarget "Everything" */;
+                       buildPhases = (
+                       );
+                       dependencies = (
+                               020DDCEA0A1E858D00E1CB49 /* PBXTargetDependency */,
+                               020DDCEC0A1E858D00E1CB49 /* PBXTargetDependency */,
+                               020DDCEE0A1E858D00E1CB49 /* PBXTargetDependency */,
+                       );
+                       name = Everything;
+                       productName = Everything;
+               };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+               0208BEB30A02D2B800255D31 /* SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208BEB10A02D2B800255D31 /* SHA1.cpp */; };
+               0208BF4D0A03137800255D31 /* Random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208BF4B0A03137800255D31 /* Random.cpp */; };
+               0208BF8C0A03E04800255D31 /* RijndaelCBCMAC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208BF8A0A03E04800255D31 /* RijndaelCBCMAC.cpp */; };
+               0208C03F0A0544BA00255D31 /* options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C03D0A0544BA00255D31 /* options.cpp */; };
+               0208C08C0A05677000255D31 /* AESKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C08B0A05677000255D31 /* AESKey.cpp */; };
+               0208C28E0A0A4E5F00255D31 /* DataSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C2880A0A4E5F00255D31 /* DataSource.cpp */; };
+               0208C2900A0A4E5F00255D31 /* Operation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */; };
+               0208C2920A0A4E5F00255D31 /* DataTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C28C0A0A4E5F00255D31 /* DataTarget.cpp */; };
+               0208C29B0A0A4EE800255D31 /* ConversionController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C2990A0A4EE800255D31 /* ConversionController.cpp */; };
+               020D41880A0FF0C20027E24E /* OutputSection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D41860A0FF0C20027E24E /* OutputSection.cpp */; };
+               020D419A0A0FF5BF0027E24E /* BootImageGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D41980A0FF5BF0027E24E /* BootImageGenerator.cpp */; };
+               020D41A60A0FF8880027E24E /* Version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D41A40A0FF8880027E24E /* Version.cpp */; };
+               020D41BA0A0FFD140027E24E /* EncoreBootImageGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D41B80A0FFD140027E24E /* EncoreBootImageGenerator.cpp */; };
+               020D43A80A14D7E20027E24E /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D43A60A14D7E20027E24E /* Logging.cpp */; };
+               020D45070A1523350027E24E /* GHSSecInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D45050A1523350027E24E /* GHSSecInfo.cpp */; };
+               020D46840A1665D90027E24E /* sbtool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D46830A1665D90027E24E /* sbtool.cpp */; };
+               020D46870A1668440027E24E /* AESKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C08B0A05677000255D31 /* AESKey.cpp */; };
+               020D46880A16684D0027E24E /* crc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F8D4EF09FEE91B004CBE69 /* crc.cpp */; };
+               020D46890A16684E0027E24E /* DataSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C2880A0A4E5F00255D31 /* DataSource.cpp */; };
+               020D468A0A16684F0027E24E /* DataTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C28C0A0A4E5F00255D31 /* DataTarget.cpp */; };
+               020D468B0A1668510027E24E /* ELFSourceFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024F1D610A0BCD8300D21D61 /* ELFSourceFile.cpp */; };
+               020D468C0A1668580027E24E /* EncoreBootImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F8D41C09FE86FA004CBE69 /* EncoreBootImage.cpp */; };
+               020D468D0A16685B0027E24E /* EvalContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E9D67409FBFE98006D7279 /* EvalContext.cpp */; };
+               020D468E0A16685D0027E24E /* GHSSecInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D45050A1523350027E24E /* GHSSecInfo.cpp */; };
+               020D468F0A16685F0027E24E /* GlobMatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 027402E40A0FB00000CF4BE7 /* GlobMatcher.cpp */; };
+               020D46900A1668600027E24E /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D43A60A14D7E20027E24E /* Logging.cpp */; };
+               020D46910A1668630027E24E /* Operation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C28A0A0A4E5F00255D31 /* Operation.cpp */; };
+               020D46920A1668650027E24E /* options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C03D0A0544BA00255D31 /* options.cpp */; };
+               020D46930A1668680027E24E /* OutputSection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D41860A0FF0C20027E24E /* OutputSection.cpp */; };
+               020D46940A1668690027E24E /* Random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208BF4B0A03137800255D31 /* Random.cpp */; };
+               020D46950A16686A0027E24E /* rijndael.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E3998D09F2EFAA0055992A /* rijndael.cpp */; };
+               020D46960A16686B0027E24E /* RijndaelCBCMAC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208BF8A0A03E04800255D31 /* RijndaelCBCMAC.cpp */; };
+               020D46970A16686D0027E24E /* SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208BEB10A02D2B800255D31 /* SHA1.cpp */; };
+               020D46980A16686F0027E24E /* SourceFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F8D5610A0152AB004CBE69 /* SourceFile.cpp */; };
+               020D46990A1668710027E24E /* SRecordSourceFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024F1D5D0A0BCD7200D21D61 /* SRecordSourceFile.cpp */; };
+               020D469A0A1668730027E24E /* stdafx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A49E09D9AE9400F80AFF /* stdafx.cpp */; };
+               020D469B0A1668760027E24E /* StELFFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A49F09D9AE9400F80AFF /* StELFFile.cpp */; };
+               020D469C0A1668770027E24E /* StExecutableImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A4A409D9AE9400F80AFF /* StExecutableImage.cpp */; };
+               020D469D0A1668780027E24E /* StSRecordFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A4AA09D9AE9400F80AFF /* StSRecordFile.cpp */; };
+               020D469E0A16687A0027E24E /* Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F8D54A0A014F5D004CBE69 /* Value.cpp */; };
+               020D469F0A16687A0027E24E /* Version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D41A40A0FF8880027E24E /* Version.cpp */; };
+               020D47A20A16C1E00027E24E /* EncoreBootImageReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D47A10A16C1E00027E24E /* EncoreBootImageReader.cpp */; };
+               020DDBED0A1D08AD00E1CB49 /* OptionDictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020DDBEB0A1D08AD00E1CB49 /* OptionDictionary.cpp */; };
+               02123F320A6B057E003CF33F /* Blob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02123F300A6B057E003CF33F /* Blob.cpp */; };
+               02123F3A0A6B09CF003CF33F /* HexValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02123F380A6B09CF003CF33F /* HexValues.cpp */; };
+               021240010A6C3AA9003CF33F /* Blob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02123F300A6B057E003CF33F /* Blob.cpp */; };
+               021240020A6C3AAA003CF33F /* HexValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02123F380A6B09CF003CF33F /* HexValues.cpp */; };
+               0215B3D309F424D800EA7C45 /* elftosb_parser.y in Sources */ = {isa = PBXBuildFile; fileRef = 0215B3D209F424D800EA7C45 /* elftosb_parser.y */; };
+               0215B3E909F4277100EA7C45 /* elftosb_lexer.l in Sources */ = {isa = PBXBuildFile; fileRef = 02E3997909F2E0410055992A /* elftosb_lexer.l */; };
+               021CA3F30A8D16960028326F /* ExcludesListMatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 021CA3F10A8D16960028326F /* ExcludesListMatcher.cpp */; };
+               022B4657121763A100A74F96 /* IVTDataSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 022B4656121763A100A74F96 /* IVTDataSource.cpp */; };
+               024F1D5F0A0BCD7200D21D61 /* SRecordSourceFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024F1D5D0A0BCD7200D21D61 /* SRecordSourceFile.cpp */; };
+               024F1D630A0BCD8300D21D61 /* ELFSourceFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 024F1D610A0BCD8300D21D61 /* ELFSourceFile.cpp */; };
+               025881010CEE47A900681C7E /* HexValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02123F380A6B09CF003CF33F /* HexValues.cpp */; };
+               027402E60A0FB00000CF4BE7 /* GlobMatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 027402E40A0FB00000CF4BE7 /* GlobMatcher.cpp */; };
+               0296A4E709D9AE9400F80AFF /* elftosb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A49309D9AE9400F80AFF /* elftosb.cpp */; };
+               0296A4F209D9AE9400F80AFF /* stdafx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A49E09D9AE9400F80AFF /* stdafx.cpp */; };
+               0296A4F309D9AE9400F80AFF /* StELFFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A49F09D9AE9400F80AFF /* StELFFile.cpp */; };
+               0296A4F809D9AE9400F80AFF /* StExecutableImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A4A409D9AE9400F80AFF /* StExecutableImage.cpp */; };
+               0296A4FE09D9AE9400F80AFF /* StSRecordFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A4AA09D9AE9400F80AFF /* StSRecordFile.cpp */; };
+               02B9D4FD0B9A13AE0084CE1F /* SB36xxBootImageGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02B9D4FC0B9A13AE0084CE1F /* SB36xxBootImageGenerator.cpp */; };
+               02B9D50A0B9A16C10084CE1F /* crypto.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02B9D5000B9A16C10084CE1F /* crypto.cpp */; };
+               02B9D50B0B9A16C10084CE1F /* St3600IPL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02B9D5020B9A16C10084CE1F /* St3600IPL.cpp */; };
+               02B9D50C0B9A16C10084CE1F /* StKeySet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02B9D5050B9A16C10084CE1F /* StKeySet.cpp */; };
+               02B9D50D0B9A16C10084CE1F /* StLFSREncrypter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02B9D5070B9A16C10084CE1F /* StLFSREncrypter.cpp */; };
+               02B9D50E0B9A16C10084CE1F /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = 02B9D5090B9A16C10084CE1F /* table.c */; };
+               02B9D56C0B9B37890084CE1F /* default_rom_key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02B9D56A0B9B37890084CE1F /* default_rom_key.cpp */; };
+               02C5DB940A925C61003B9C11 /* format_string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */; };
+               02C5DB950A925C61003B9C11 /* format_string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */; };
+               02C5DB960A925C61003B9C11 /* format_string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02C5DB920A925C61003B9C11 /* format_string.cpp */; };
+               02CD157609F543FE00ABE650 /* ElftosbAST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02CD157409F543FE00ABE650 /* ElftosbAST.cpp */; };
+               02CD158909F557D300ABE650 /* ElftosbLexer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02CD158809F557D300ABE650 /* ElftosbLexer.cpp */; };
+               02D1FCA90BD02B69007C7450 /* SearchPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02D1FCA80BD02B69007C7450 /* SearchPath.cpp */; };
+               02D1FCF70BD039A0007C7450 /* SearchPath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02D1FCA80BD02B69007C7450 /* SearchPath.cpp */; };
+               02E25EAA0A1A5DCB001161B5 /* keygen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E25EA90A1A5DCB001161B5 /* keygen.cpp */; };
+               02E25EAE0A1A5DF4001161B5 /* AESKey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C08B0A05677000255D31 /* AESKey.cpp */; };
+               02E25EAF0A1A5E09001161B5 /* Random.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208BF4B0A03137800255D31 /* Random.cpp */; };
+               02E25EB00A1A5E0C001161B5 /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 020D43A60A14D7E20027E24E /* Logging.cpp */; };
+               02E25EB10A1A5E18001161B5 /* stdafx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0296A49E09D9AE9400F80AFF /* stdafx.cpp */; };
+               02E25EB20A1A5E1C001161B5 /* options.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0208C03D0A0544BA00255D31 /* options.cpp */; };
+               02E3998F09F2EFAA0055992A /* rijndael.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E3998D09F2EFAA0055992A /* rijndael.cpp */; };
+               02E535B50C245AEC00CBD4A5 /* DataSourceImager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E535B40C245AEC00CBD4A5 /* DataSourceImager.cpp */; };
+               02E9D67609FBFE98006D7279 /* EvalContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02E9D67409FBFE98006D7279 /* EvalContext.cpp */; };
+               02F8D41E09FE86FB004CBE69 /* EncoreBootImage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F8D41C09FE86FA004CBE69 /* EncoreBootImage.cpp */; };
+               02F8D4F109FEE91B004CBE69 /* crc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F8D4EF09FEE91B004CBE69 /* crc.cpp */; };
+               02F8D54C0A014F5D004CBE69 /* Value.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F8D54A0A014F5D004CBE69 /* Value.cpp */; };
+               02F8D5630A0152AB004CBE69 /* SourceFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 02F8D5610A0152AB004CBE69 /* SourceFile.cpp */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXBuildRule section */
+               0215B3D509F4254100EA7C45 /* PBXBuildRule */ = {
+                       isa = PBXBuildRule;
+                       compilerSpec = com.apple.compilers.proxy.script;
+                       fileType = sourcecode.lex;
+                       isEditable = 1;
+                       outputFiles = (
+                               "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.cpp",
+                       );
+                       script = "flex -o${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.cpp ${INPUT_FILE_DIR}/${INPUT_FILE_NAME}";
+               };
+               0215B3D609F4255D00EA7C45 /* PBXBuildRule */ = {
+                       isa = PBXBuildRule;
+                       compilerSpec = com.apple.compilers.proxy.script;
+                       fileType = sourcecode.yacc;
+                       isEditable = 1;
+                       outputFiles = (
+                               "${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.tab.cpp",
+                       );
+                       script = "/usr/local/bin/bison -o ${DERIVED_FILES_DIR}/${INPUT_FILE_BASE}.tab.cpp ${INPUT_FILE_DIR}/${INPUT_FILE_NAME}";
+               };
+               0296CF9309DB3B8700F80AFF /* PBXBuildRule */ = {
+                       isa = PBXBuildRule;
+                       compilerSpec = com.apple.compilers.gcc;
+                       fileType = sourcecode.c;
+                       isEditable = 1;
+                       outputFiles = (
+                       );
+               };
+/* End PBXBuildRule section */
+
+/* Begin PBXContainerItemProxy section */
+               020DDCE90A1E858D00E1CB49 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 8DD76F620486A84900D96B5E;
+                       remoteInfo = elftosb;
+               };
+               020DDCEB0A1E858D00E1CB49 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 020D467A0A16657C0027E24E;
+                       remoteInfo = sbtool;
+               };
+               020DDCED0A1E858D00E1CB49 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 02E25EA40A1A5DB0001161B5;
+                       remoteInfo = keygen;
+               };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+               0208BEB10A02D2B800255D31 /* SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SHA1.cpp; sourceTree = "<group>"; };
+               0208BEB20A02D2B800255D31 /* SHA1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SHA1.h; sourceTree = "<group>"; };
+               0208BF4A0A03137800255D31 /* Random.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Random.h; sourceTree = "<group>"; };
+               0208BF4B0A03137800255D31 /* Random.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Random.cpp; sourceTree = "<group>"; };
+               0208BF890A03E04800255D31 /* RijndaelCBCMAC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RijndaelCBCMAC.h; sourceTree = "<group>"; };
+               0208BF8A0A03E04800255D31 /* RijndaelCBCMAC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RijndaelCBCMAC.cpp; sourceTree = "<group>"; };
+               0208C03D0A0544BA00255D31 /* options.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = options.cpp; sourceTree = "<group>"; };
+               0208C03E0A0544BA00255D31 /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = options.h; sourceTree = "<group>"; };
+               0208C08B0A05677000255D31 /* AESKey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AESKey.cpp; sourceTree = "<group>"; };
+               0208C2880A0A4E5F00255D31 /* DataSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataSource.cpp; sourceTree = "<group>"; };
+               0208C2890A0A4E5F00255D31 /* DataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSource.h; sourceTree = "<group>"; };
+               0208C28A0A0A4E5F00255D31 /* Operation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Operation.cpp; sourceTree = "<group>"; };
+               0208C28B0A0A4E5F00255D31 /* Operation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Operation.h; sourceTree = "<group>"; };
+               0208C28C0A0A4E5F00255D31 /* DataTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataTarget.cpp; sourceTree = "<group>"; };
+               0208C28D0A0A4E5F00255D31 /* DataTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataTarget.h; sourceTree = "<group>"; };
+               0208C2990A0A4EE800255D31 /* ConversionController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConversionController.cpp; sourceTree = "<group>"; };
+               0208C29A0A0A4EE800255D31 /* ConversionController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConversionController.h; sourceTree = "<group>"; };
+               0208C2E00A0AA4F700255D31 /* int_size.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = int_size.h; sourceTree = "<group>"; };
+               020D416A0A0FE8AC0027E24E /* StringMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringMatcher.h; sourceTree = "<group>"; };
+               020D41850A0FF0C20027E24E /* OutputSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputSection.h; sourceTree = "<group>"; };
+               020D41860A0FF0C20027E24E /* OutputSection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputSection.cpp; sourceTree = "<group>"; };
+               020D41970A0FF5BF0027E24E /* BootImageGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BootImageGenerator.h; sourceTree = "<group>"; };
+               020D41980A0FF5BF0027E24E /* BootImageGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BootImageGenerator.cpp; sourceTree = "<group>"; };
+               020D41A30A0FF8880027E24E /* Version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Version.h; sourceTree = "<group>"; };
+               020D41A40A0FF8880027E24E /* Version.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Version.cpp; sourceTree = "<group>"; };
+               020D41AE0A0FFB040027E24E /* BootImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BootImage.h; sourceTree = "<group>"; };
+               020D41B70A0FFD140027E24E /* EncoreBootImageGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncoreBootImageGenerator.h; sourceTree = "<group>"; };
+               020D41B80A0FFD140027E24E /* EncoreBootImageGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EncoreBootImageGenerator.cpp; sourceTree = "<group>"; };
+               020D43A50A14D7E20027E24E /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = "<group>"; };
+               020D43A60A14D7E20027E24E /* Logging.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Logging.cpp; sourceTree = "<group>"; };
+               020D45040A1523350027E24E /* GHSSecInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHSSecInfo.h; sourceTree = "<group>"; };
+               020D45050A1523350027E24E /* GHSSecInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GHSSecInfo.cpp; sourceTree = "<group>"; };
+               020D454F0A1533550027E24E /* OptionContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionContext.h; sourceTree = "<group>"; };
+               020D467B0A16657C0027E24E /* sbtool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = sbtool; sourceTree = BUILT_PRODUCTS_DIR; };
+               020D46830A1665D90027E24E /* sbtool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sbtool.cpp; sourceTree = "<group>"; };
+               020D47A00A16C1E00027E24E /* EncoreBootImageReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncoreBootImageReader.h; sourceTree = "<group>"; };
+               020D47A10A16C1E00027E24E /* EncoreBootImageReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EncoreBootImageReader.cpp; sourceTree = "<group>"; };
+               020DDBEA0A1D08AD00E1CB49 /* OptionDictionary.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionDictionary.h; sourceTree = "<group>"; };
+               020DDBEB0A1D08AD00E1CB49 /* OptionDictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OptionDictionary.cpp; sourceTree = "<group>"; };
+               02123F2F0A6B057E003CF33F /* Blob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Blob.h; sourceTree = "<group>"; };
+               02123F300A6B057E003CF33F /* Blob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Blob.cpp; sourceTree = "<group>"; };
+               02123F370A6B09CF003CF33F /* HexValues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HexValues.h; sourceTree = "<group>"; };
+               02123F380A6B09CF003CF33F /* HexValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HexValues.cpp; sourceTree = "<group>"; };
+               0215B3BA09F3FBF100EA7C45 /* ElftosbLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElftosbLexer.h; sourceTree = "<group>"; };
+               0215B3D209F424D800EA7C45 /* elftosb_parser.y */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.yacc; path = elftosb_parser.y; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
+               021CA3F00A8D16960028326F /* ExcludesListMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExcludesListMatcher.h; sourceTree = "<group>"; };
+               021CA3F10A8D16960028326F /* ExcludesListMatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExcludesListMatcher.cpp; sourceTree = "<group>"; };
+               022B4655121763A100A74F96 /* IVTDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IVTDataSource.h; sourceTree = "<group>"; };
+               022B4656121763A100A74F96 /* IVTDataSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IVTDataSource.cpp; sourceTree = "<group>"; };
+               024F1D5C0A0BCD7200D21D61 /* SRecordSourceFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SRecordSourceFile.h; sourceTree = "<group>"; };
+               024F1D5D0A0BCD7200D21D61 /* SRecordSourceFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SRecordSourceFile.cpp; sourceTree = "<group>"; };
+               024F1D600A0BCD8300D21D61 /* ELFSourceFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ELFSourceFile.h; sourceTree = "<group>"; };
+               024F1D610A0BCD8300D21D61 /* ELFSourceFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ELFSourceFile.cpp; sourceTree = "<group>"; };
+               024F1E190A0D20C900D21D61 /* ElftosbErrors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElftosbErrors.h; sourceTree = "<group>"; };
+               027402E30A0FB00000CF4BE7 /* GlobMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlobMatcher.h; sourceTree = "<group>"; };
+               027402E40A0FB00000CF4BE7 /* GlobMatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GlobMatcher.cpp; sourceTree = "<group>"; };
+               0296A48709D9AE9400F80AFF /* ELF.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ELF.h; sourceTree = "<group>"; };
+               0296A48909D9AE9400F80AFF /* hello_NOR_arm */ = {isa = PBXFileReference; lastKnownFileType = file; path = hello_NOR_arm; sourceTree = "<group>"; };
+               0296A48A09D9AE9400F80AFF /* hello_NOR_arm.map */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = hello_NOR_arm.map; sourceTree = "<group>"; };
+               0296A48B09D9AE9400F80AFF /* hello_NOR_mixed */ = {isa = PBXFileReference; lastKnownFileType = file; path = hello_NOR_mixed; sourceTree = "<group>"; };
+               0296A48C09D9AE9400F80AFF /* hello_NOR_mixed.map */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = hello_NOR_mixed.map; sourceTree = "<group>"; };
+               0296A48D09D9AE9400F80AFF /* hello_NOR_thumb */ = {isa = PBXFileReference; lastKnownFileType = file; path = hello_NOR_thumb; sourceTree = "<group>"; };
+               0296A48E09D9AE9400F80AFF /* hello_NOR_thumb.map */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = hello_NOR_thumb.map; sourceTree = "<group>"; };
+               0296A48F09D9AE9400F80AFF /* hostlink */ = {isa = PBXFileReference; lastKnownFileType = file; path = hostlink; sourceTree = "<group>"; };
+               0296A49009D9AE9400F80AFF /* redboot_gcc.srec */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = redboot_gcc.srec; sourceTree = "<group>"; };
+               0296A49109D9AE9400F80AFF /* sd_player_gcc */ = {isa = PBXFileReference; lastKnownFileType = file; path = sd_player_gcc; sourceTree = "<group>"; };
+               0296A49209D9AE9400F80AFF /* sd_player_gcc.srec */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = sd_player_gcc.srec; sourceTree = "<group>"; };
+               0296A49309D9AE9400F80AFF /* elftosb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = elftosb.cpp; sourceTree = "<group>"; tabWidth = 4; usesTabs = 1; };
+               0296A49409D9AE9400F80AFF /* elftosb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = elftosb.h; sourceTree = "<group>"; };
+               0296A49E09D9AE9400F80AFF /* stdafx.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = stdafx.cpp; sourceTree = "<group>"; };
+               0296A49F09D9AE9400F80AFF /* StELFFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = StELFFile.cpp; sourceTree = "<group>"; };
+               0296A4A009D9AE9400F80AFF /* StELFFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StELFFile.h; sourceTree = "<group>"; };
+               0296A4A409D9AE9400F80AFF /* StExecutableImage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = StExecutableImage.cpp; sourceTree = "<group>"; };
+               0296A4A509D9AE9400F80AFF /* StExecutableImage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StExecutableImage.h; sourceTree = "<group>"; };
+               0296A4AA09D9AE9400F80AFF /* StSRecordFile.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = StSRecordFile.cpp; sourceTree = "<group>"; };
+               0296A4AB09D9AE9400F80AFF /* StSRecordFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = StSRecordFile.h; sourceTree = "<group>"; };
+               0296CF9C09DB3C5200F80AFF /* stdafx.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = stdafx.h; sourceTree = "<group>"; };
+               02B9D4FB0B9A13AE0084CE1F /* SB36xxBootImageGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SB36xxBootImageGenerator.h; sourceTree = "<group>"; };
+               02B9D4FC0B9A13AE0084CE1F /* SB36xxBootImageGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SB36xxBootImageGenerator.cpp; sourceTree = "<group>"; };
+               02B9D5000B9A16C10084CE1F /* crypto.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = crypto.cpp; sourceTree = "<group>"; };
+               02B9D5010B9A16C10084CE1F /* crypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crypto.h; sourceTree = "<group>"; };
+               02B9D5020B9A16C10084CE1F /* St3600IPL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = St3600IPL.cpp; sourceTree = "<group>"; };
+               02B9D5030B9A16C10084CE1F /* St3600IPL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = St3600IPL.h; sourceTree = "<group>"; };
+               02B9D5040B9A16C10084CE1F /* StEncrypter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StEncrypter.h; sourceTree = "<group>"; };
+               02B9D5050B9A16C10084CE1F /* StKeySet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StKeySet.cpp; sourceTree = "<group>"; };
+               02B9D5060B9A16C10084CE1F /* StKeySet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StKeySet.h; sourceTree = "<group>"; };
+               02B9D5070B9A16C10084CE1F /* StLFSREncrypter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StLFSREncrypter.cpp; sourceTree = "<group>"; };
+               02B9D5080B9A16C10084CE1F /* StLFSREncrypter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StLFSREncrypter.h; sourceTree = "<group>"; };
+               02B9D5090B9A16C10084CE1F /* table.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = table.c; sourceTree = "<group>"; };
+               02B9D56A0B9B37890084CE1F /* default_rom_key.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = default_rom_key.cpp; sourceTree = "<group>"; };
+               02B9D56B0B9B37890084CE1F /* default_rom_key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = default_rom_key.h; sourceTree = "<group>"; };
+               02C5DB910A925C61003B9C11 /* format_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = format_string.h; sourceTree = "<group>"; };
+               02C5DB920A925C61003B9C11 /* format_string.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = format_string.cpp; sourceTree = "<group>"; };
+               02C5DC000A93AC85003B9C11 /* EndianUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EndianUtilities.h; sourceTree = "<group>"; };
+               02CD157309F543FE00ABE650 /* ElftosbAST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElftosbAST.h; sourceTree = "<group>"; };
+               02CD157409F543FE00ABE650 /* ElftosbAST.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ElftosbAST.cpp; sourceTree = "<group>"; };
+               02CD158809F557D300ABE650 /* ElftosbLexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ElftosbLexer.cpp; sourceTree = "<group>"; };
+               02D1FCA70BD02B69007C7450 /* SearchPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchPath.h; sourceTree = "<group>"; };
+               02D1FCA80BD02B69007C7450 /* SearchPath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SearchPath.cpp; sourceTree = "<group>"; };
+               02D46C100FED492400E65706 /* elftosb_lexer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = elftosb_lexer.cpp; path = build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_lexer.cpp; sourceTree = SOURCE_ROOT; };
+               02D46C110FED492400E65706 /* elftosb_parser.tab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = elftosb_parser.tab.cpp; path = build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp; sourceTree = SOURCE_ROOT; };
+               02D46C120FED492400E65706 /* elftosb_parser.tab.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = elftosb_parser.tab.hpp; path = build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.hpp; sourceTree = SOURCE_ROOT; };
+               02DC603C0A7AAA7A0027E7F9 /* index.html */ = {isa = PBXFileReference; explicitFileType = text.html.documentation; fileEncoding = 4; name = index.html; path = elftosb2/html/index.html; sourceTree = "<group>"; };
+               02E25EA50A1A5DB0001161B5 /* keygen */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = keygen; sourceTree = BUILT_PRODUCTS_DIR; };
+               02E25EA90A1A5DCB001161B5 /* keygen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = keygen.cpp; sourceTree = "<group>"; };
+               02E3997909F2E0410055992A /* elftosb_lexer.l */ = {isa = PBXFileReference; explicitFileType = sourcecode.lex; fileEncoding = 4; path = elftosb_lexer.l; sourceTree = "<group>"; };
+               02E3998909F2ED990055992A /* FlexLexer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FlexLexer.h; sourceTree = "<group>"; };
+               02E3998D09F2EFAA0055992A /* rijndael.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rijndael.cpp; sourceTree = "<group>"; };
+               02E3998E09F2EFAA0055992A /* rijndael.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rijndael.h; sourceTree = "<group>"; };
+               02E535B30C245AEC00CBD4A5 /* DataSourceImager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataSourceImager.h; sourceTree = "<group>"; };
+               02E535B40C245AEC00CBD4A5 /* DataSourceImager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DataSourceImager.cpp; sourceTree = "<group>"; };
+               02E9D5B009FA8AE4006D7279 /* smart_ptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = smart_ptr.h; sourceTree = "<group>"; };
+               02E9D67309FBFE97006D7279 /* EvalContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EvalContext.h; sourceTree = "<group>"; };
+               02E9D67409FBFE98006D7279 /* EvalContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EvalContext.cpp; sourceTree = "<group>"; };
+               02F8D41B09FE86FA004CBE69 /* EncoreBootImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncoreBootImage.h; sourceTree = "<group>"; };
+               02F8D41C09FE86FA004CBE69 /* EncoreBootImage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EncoreBootImage.cpp; sourceTree = "<group>"; };
+               02F8D46509FEA584004CBE69 /* AESKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AESKey.h; sourceTree = "<group>"; };
+               02F8D4EF09FEE91B004CBE69 /* crc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = crc.cpp; sourceTree = "<group>"; };
+               02F8D4F009FEE91B004CBE69 /* crc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crc.h; sourceTree = "<group>"; };
+               02F8D5490A014F5D004CBE69 /* Value.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Value.h; sourceTree = "<group>"; };
+               02F8D54A0A014F5D004CBE69 /* Value.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Value.cpp; sourceTree = "<group>"; };
+               02F8D5600A0152AB004CBE69 /* SourceFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceFile.h; sourceTree = "<group>"; };
+               02F8D5610A0152AB004CBE69 /* SourceFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceFile.cpp; sourceTree = "<group>"; };
+               02FE65030BFE669B004A1450 /* basic_test_cmd.e */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = basic_test_cmd.e; sourceTree = "<group>"; };
+               02FE65040BFE669B004A1450 /* complex.bd */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = complex.bd; sourceTree = "<group>"; };
+               02FE65050BFE669B004A1450 /* simple.e */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = simple.e; sourceTree = "<group>"; };
+               02FE65060BFE669B004A1450 /* test_cmd.e */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = test_cmd.e; sourceTree = "<group>"; };
+               02FE65860C0522B0004A1450 /* todo.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = todo.txt; path = elftosb2/todo.txt; sourceTree = "<group>"; };
+               8DD76F6C0486A84900D96B5E /* elftosb */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = elftosb; sourceTree = BUILT_PRODUCTS_DIR; };
+               C6859E8B029090EE04C91782 /* elftosb.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = elftosb.1; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               020D46790A16657C0027E24E /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               02E25EA30A1A5DB0001161B5 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               8DD76F660486A84900D96B5E /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               020D46810A1665A20027E24E /* sbtool */ = {
+                       isa = PBXGroup;
+                       children = (
+                               020D46830A1665D90027E24E /* sbtool.cpp */,
+                               020D47A00A16C1E00027E24E /* EncoreBootImageReader.h */,
+                               020D47A10A16C1E00027E24E /* EncoreBootImageReader.cpp */,
+                       );
+                       path = sbtool;
+                       sourceTree = "<group>";
+               };
+               020D47700A1691F10027E24E /* common */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0208C08B0A05677000255D31 /* AESKey.cpp */,
+                               02F8D46509FEA584004CBE69 /* AESKey.h */,
+                               02123F300A6B057E003CF33F /* Blob.cpp */,
+                               02123F2F0A6B057E003CF33F /* Blob.h */,
+                               020D41AE0A0FFB040027E24E /* BootImage.h */,
+                               02F8D4EF09FEE91B004CBE69 /* crc.cpp */,
+                               02F8D4F009FEE91B004CBE69 /* crc.h */,
+                               0208C2880A0A4E5F00255D31 /* DataSource.cpp */,
+                               0208C2890A0A4E5F00255D31 /* DataSource.h */,
+                               02E535B40C245AEC00CBD4A5 /* DataSourceImager.cpp */,
+                               02E535B30C245AEC00CBD4A5 /* DataSourceImager.h */,
+                               0208C28C0A0A4E5F00255D31 /* DataTarget.cpp */,
+                               0208C28D0A0A4E5F00255D31 /* DataTarget.h */,
+                               0296A48709D9AE9400F80AFF /* ELF.h */,
+                               024F1D610A0BCD8300D21D61 /* ELFSourceFile.cpp */,
+                               024F1D600A0BCD8300D21D61 /* ELFSourceFile.h */,
+                               02F8D41C09FE86FA004CBE69 /* EncoreBootImage.cpp */,
+                               02F8D41B09FE86FA004CBE69 /* EncoreBootImage.h */,
+                               02C5DC000A93AC85003B9C11 /* EndianUtilities.h */,
+                               02E9D67409FBFE98006D7279 /* EvalContext.cpp */,
+                               02E9D67309FBFE97006D7279 /* EvalContext.h */,
+                               021CA3F10A8D16960028326F /* ExcludesListMatcher.cpp */,
+                               021CA3F00A8D16960028326F /* ExcludesListMatcher.h */,
+                               02C5DB920A925C61003B9C11 /* format_string.cpp */,
+                               02C5DB910A925C61003B9C11 /* format_string.h */,
+                               020D45050A1523350027E24E /* GHSSecInfo.cpp */,
+                               020D45040A1523350027E24E /* GHSSecInfo.h */,
+                               027402E40A0FB00000CF4BE7 /* GlobMatcher.cpp */,
+                               027402E30A0FB00000CF4BE7 /* GlobMatcher.h */,
+                               02123F380A6B09CF003CF33F /* HexValues.cpp */,
+                               02123F370A6B09CF003CF33F /* HexValues.h */,
+                               0208C2E00A0AA4F700255D31 /* int_size.h */,
+                               020D43A60A14D7E20027E24E /* Logging.cpp */,
+                               020D43A50A14D7E20027E24E /* Logging.h */,
+                               0208C28A0A0A4E5F00255D31 /* Operation.cpp */,
+                               0208C28B0A0A4E5F00255D31 /* Operation.h */,
+                               020D454F0A1533550027E24E /* OptionContext.h */,
+                               020DDBEB0A1D08AD00E1CB49 /* OptionDictionary.cpp */,
+                               020DDBEA0A1D08AD00E1CB49 /* OptionDictionary.h */,
+                               0208C03D0A0544BA00255D31 /* options.cpp */,
+                               0208C03E0A0544BA00255D31 /* options.h */,
+                               020D41860A0FF0C20027E24E /* OutputSection.cpp */,
+                               020D41850A0FF0C20027E24E /* OutputSection.h */,
+                               0208BF4B0A03137800255D31 /* Random.cpp */,
+                               0208BF4A0A03137800255D31 /* Random.h */,
+                               02E3998D09F2EFAA0055992A /* rijndael.cpp */,
+                               02E3998E09F2EFAA0055992A /* rijndael.h */,
+                               0208BF8A0A03E04800255D31 /* RijndaelCBCMAC.cpp */,
+                               0208BF890A03E04800255D31 /* RijndaelCBCMAC.h */,
+                               02D1FCA80BD02B69007C7450 /* SearchPath.cpp */,
+                               02D1FCA70BD02B69007C7450 /* SearchPath.h */,
+                               0208BEB10A02D2B800255D31 /* SHA1.cpp */,
+                               0208BEB20A02D2B800255D31 /* SHA1.h */,
+                               02E9D5B009FA8AE4006D7279 /* smart_ptr.h */,
+                               02F8D5610A0152AB004CBE69 /* SourceFile.cpp */,
+                               02F8D5600A0152AB004CBE69 /* SourceFile.h */,
+                               024F1D5D0A0BCD7200D21D61 /* SRecordSourceFile.cpp */,
+                               024F1D5C0A0BCD7200D21D61 /* SRecordSourceFile.h */,
+                               0296A49E09D9AE9400F80AFF /* stdafx.cpp */,
+                               0296CF9C09DB3C5200F80AFF /* stdafx.h */,
+                               0296A49F09D9AE9400F80AFF /* StELFFile.cpp */,
+                               0296A4A009D9AE9400F80AFF /* StELFFile.h */,
+                               0296A4A409D9AE9400F80AFF /* StExecutableImage.cpp */,
+                               0296A4A509D9AE9400F80AFF /* StExecutableImage.h */,
+                               020D416A0A0FE8AC0027E24E /* StringMatcher.h */,
+                               0296A4AA09D9AE9400F80AFF /* StSRecordFile.cpp */,
+                               0296A4AB09D9AE9400F80AFF /* StSRecordFile.h */,
+                               02F8D54A0A014F5D004CBE69 /* Value.cpp */,
+                               02F8D5490A014F5D004CBE69 /* Value.h */,
+                               020D41A40A0FF8880027E24E /* Version.cpp */,
+                               020D41A30A0FF8880027E24E /* Version.h */,
+                               022B4655121763A100A74F96 /* IVTDataSource.h */,
+                               022B4656121763A100A74F96 /* IVTDataSource.cpp */,
+                       );
+                       path = common;
+                       sourceTree = "<group>";
+               };
+               0296A45909D9AE9400F80AFF /* elftosb2 */ = {
+                       isa = PBXGroup;
+                       children = (
+                               02D46C140FED492C00E65706 /* Derived Sources */,
+                               020D41980A0FF5BF0027E24E /* BootImageGenerator.cpp */,
+                               020D41970A0FF5BF0027E24E /* BootImageGenerator.h */,
+                               0208C2990A0A4EE800255D31 /* ConversionController.cpp */,
+                               0208C29A0A0A4EE800255D31 /* ConversionController.h */,
+                               02B9D5000B9A16C10084CE1F /* crypto.cpp */,
+                               02B9D5010B9A16C10084CE1F /* crypto.h */,
+                               02B9D56A0B9B37890084CE1F /* default_rom_key.cpp */,
+                               02B9D56B0B9B37890084CE1F /* default_rom_key.h */,
+                               0296A49309D9AE9400F80AFF /* elftosb.cpp */,
+                               0296A49409D9AE9400F80AFF /* elftosb.h */,
+                               02E3997909F2E0410055992A /* elftosb_lexer.l */,
+                               0215B3D209F424D800EA7C45 /* elftosb_parser.y */,
+                               02CD157409F543FE00ABE650 /* ElftosbAST.cpp */,
+                               02CD157309F543FE00ABE650 /* ElftosbAST.h */,
+                               024F1E190A0D20C900D21D61 /* ElftosbErrors.h */,
+                               02CD158809F557D300ABE650 /* ElftosbLexer.cpp */,
+                               0215B3BA09F3FBF100EA7C45 /* ElftosbLexer.h */,
+                               020D41B80A0FFD140027E24E /* EncoreBootImageGenerator.cpp */,
+                               020D41B70A0FFD140027E24E /* EncoreBootImageGenerator.h */,
+                               02E3998909F2ED990055992A /* FlexLexer.h */,
+                               02B9D4FC0B9A13AE0084CE1F /* SB36xxBootImageGenerator.cpp */,
+                               02B9D4FB0B9A13AE0084CE1F /* SB36xxBootImageGenerator.h */,
+                               02B9D5020B9A16C10084CE1F /* St3600IPL.cpp */,
+                               02B9D5030B9A16C10084CE1F /* St3600IPL.h */,
+                               02B9D5040B9A16C10084CE1F /* StEncrypter.h */,
+                               02B9D5050B9A16C10084CE1F /* StKeySet.cpp */,
+                               02B9D5060B9A16C10084CE1F /* StKeySet.h */,
+                               02B9D5070B9A16C10084CE1F /* StLFSREncrypter.cpp */,
+                               02B9D5080B9A16C10084CE1F /* StLFSREncrypter.h */,
+                               02B9D5090B9A16C10084CE1F /* table.c */,
+                       );
+                       path = elftosb2;
+                       sourceTree = "<group>";
+               };
+               0296A48809D9AE9400F80AFF /* test_files */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0296A48909D9AE9400F80AFF /* hello_NOR_arm */,
+                               0296A48A09D9AE9400F80AFF /* hello_NOR_arm.map */,
+                               0296A48B09D9AE9400F80AFF /* hello_NOR_mixed */,
+                               0296A48C09D9AE9400F80AFF /* hello_NOR_mixed.map */,
+                               0296A48D09D9AE9400F80AFF /* hello_NOR_thumb */,
+                               0296A48E09D9AE9400F80AFF /* hello_NOR_thumb.map */,
+                               0296A48F09D9AE9400F80AFF /* hostlink */,
+                               0296A49009D9AE9400F80AFF /* redboot_gcc.srec */,
+                               0296A49109D9AE9400F80AFF /* sd_player_gcc */,
+                               0296A49209D9AE9400F80AFF /* sd_player_gcc.srec */,
+                       );
+                       path = test_files;
+                       sourceTree = "<group>";
+               };
+               02D46C140FED492C00E65706 /* Derived Sources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               02D46C100FED492400E65706 /* elftosb_lexer.cpp */,
+                               02D46C110FED492400E65706 /* elftosb_parser.tab.cpp */,
+                               02D46C120FED492400E65706 /* elftosb_parser.tab.hpp */,
+                       );
+                       name = "Derived Sources";
+                       sourceTree = "<group>";
+               };
+               02E25EA70A1A5DCB001161B5 /* keygen */ = {
+                       isa = PBXGroup;
+                       children = (
+                               02E25EA90A1A5DCB001161B5 /* keygen.cpp */,
+                       );
+                       path = keygen;
+                       sourceTree = "<group>";
+               };
+               02FE65020BFE669B004A1450 /* bdfiles */ = {
+                       isa = PBXGroup;
+                       children = (
+                               02FE65030BFE669B004A1450 /* basic_test_cmd.e */,
+                               02FE65040BFE669B004A1450 /* complex.bd */,
+                               02FE65050BFE669B004A1450 /* simple.e */,
+                               02FE65060BFE669B004A1450 /* test_cmd.e */,
+                       );
+                       path = bdfiles;
+                       sourceTree = "<group>";
+               };
+               08FB7794FE84155DC02AAC07 /* elftosb */ = {
+                       isa = PBXGroup;
+                       children = (
+                               02FE65860C0522B0004A1450 /* todo.txt */,
+                               02FE65020BFE669B004A1450 /* bdfiles */,
+                               08FB7795FE84155DC02AAC07 /* Source */,
+                               C6859E8C029090F304C91782 /* Documentation */,
+                               1AB674ADFE9D54B511CA2CBB /* Products */,
+                       );
+                       name = elftosb;
+                       sourceTree = "<group>";
+               };
+               08FB7795FE84155DC02AAC07 /* Source */ = {
+                       isa = PBXGroup;
+                       children = (
+                               0296A48809D9AE9400F80AFF /* test_files */,
+                               02E25EA70A1A5DCB001161B5 /* keygen */,
+                               020D46810A1665A20027E24E /* sbtool */,
+                               0296A45909D9AE9400F80AFF /* elftosb2 */,
+                               020D47700A1691F10027E24E /* common */,
+                       );
+                       name = Source;
+                       sourceTree = "<group>";
+               };
+               1AB674ADFE9D54B511CA2CBB /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               8DD76F6C0486A84900D96B5E /* elftosb */,
+                               020D467B0A16657C0027E24E /* sbtool */,
+                               02E25EA50A1A5DB0001161B5 /* keygen */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               C6859E8C029090F304C91782 /* Documentation */ = {
+                       isa = PBXGroup;
+                       children = (
+                               02DC603C0A7AAA7A0027E7F9 /* index.html */,
+                               C6859E8B029090EE04C91782 /* elftosb.1 */,
+                       );
+                       name = Documentation;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+               020D467A0A16657C0027E24E /* sbtool */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 020D467E0A1665890027E24E /* Build configuration list for PBXNativeTarget "sbtool" */;
+                       buildPhases = (
+                               020D46780A16657C0027E24E /* Sources */,
+                               020D46790A16657C0027E24E /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = sbtool;
+                       productName = sbtool;
+                       productReference = 020D467B0A16657C0027E24E /* sbtool */;
+                       productType = "com.apple.product-type.tool";
+               };
+               02E25EA40A1A5DB0001161B5 /* keygen */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 02E25EAB0A1A5DCB001161B5 /* Build configuration list for PBXNativeTarget "keygen" */;
+                       buildPhases = (
+                               02E25EA20A1A5DB0001161B5 /* Sources */,
+                               02E25EA30A1A5DB0001161B5 /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = keygen;
+                       productName = keygen;
+                       productReference = 02E25EA50A1A5DB0001161B5 /* keygen */;
+                       productType = "com.apple.product-type.tool";
+               };
+               8DD76F620486A84900D96B5E /* elftosb */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "elftosb" */;
+                       buildPhases = (
+                               8DD76F640486A84900D96B5E /* Sources */,
+                               8DD76F660486A84900D96B5E /* Frameworks */,
+                       );
+                       buildRules = (
+                               0215B3D609F4255D00EA7C45 /* PBXBuildRule */,
+                               0215B3D509F4254100EA7C45 /* PBXBuildRule */,
+                               0296CF9309DB3B8700F80AFF /* PBXBuildRule */,
+                       );
+                       dependencies = (
+                       );
+                       name = elftosb;
+                       productInstallPath = "$(HOME)/bin";
+                       productName = elftosb;
+                       productReference = 8DD76F6C0486A84900D96B5E /* elftosb */;
+                       productType = "com.apple.product-type.tool";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               08FB7793FE84155DC02AAC07 /* Project object */ = {
+                       isa = PBXProject;
+                       buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "elftosb" */;
+                       compatibilityVersion = "Xcode 3.1";
+                       hasScannedForEncodings = 1;
+                       mainGroup = 08FB7794FE84155DC02AAC07 /* elftosb */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               8DD76F620486A84900D96B5E /* elftosb */,
+                               020D467A0A16657C0027E24E /* sbtool */,
+                               02E25EA40A1A5DB0001161B5 /* keygen */,
+                               020DDCE80A1E858600E1CB49 /* Everything */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+               020D46780A16657C0027E24E /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               020D46840A1665D90027E24E /* sbtool.cpp in Sources */,
+                               020D46870A1668440027E24E /* AESKey.cpp in Sources */,
+                               020D46880A16684D0027E24E /* crc.cpp in Sources */,
+                               020D46890A16684E0027E24E /* DataSource.cpp in Sources */,
+                               020D468A0A16684F0027E24E /* DataTarget.cpp in Sources */,
+                               020D468B0A1668510027E24E /* ELFSourceFile.cpp in Sources */,
+                               020D468C0A1668580027E24E /* EncoreBootImage.cpp in Sources */,
+                               020D468D0A16685B0027E24E /* EvalContext.cpp in Sources */,
+                               020D468E0A16685D0027E24E /* GHSSecInfo.cpp in Sources */,
+                               020D468F0A16685F0027E24E /* GlobMatcher.cpp in Sources */,
+                               020D46900A1668600027E24E /* Logging.cpp in Sources */,
+                               020D46910A1668630027E24E /* Operation.cpp in Sources */,
+                               020D46920A1668650027E24E /* options.cpp in Sources */,
+                               020D46930A1668680027E24E /* OutputSection.cpp in Sources */,
+                               020D46940A1668690027E24E /* Random.cpp in Sources */,
+                               020D46950A16686A0027E24E /* rijndael.cpp in Sources */,
+                               020D46960A16686B0027E24E /* RijndaelCBCMAC.cpp in Sources */,
+                               020D46970A16686D0027E24E /* SHA1.cpp in Sources */,
+                               020D46980A16686F0027E24E /* SourceFile.cpp in Sources */,
+                               020D46990A1668710027E24E /* SRecordSourceFile.cpp in Sources */,
+                               020D469A0A1668730027E24E /* stdafx.cpp in Sources */,
+                               020D469B0A1668760027E24E /* StELFFile.cpp in Sources */,
+                               020D469C0A1668770027E24E /* StExecutableImage.cpp in Sources */,
+                               020D469D0A1668780027E24E /* StSRecordFile.cpp in Sources */,
+                               020D469E0A16687A0027E24E /* Value.cpp in Sources */,
+                               020D469F0A16687A0027E24E /* Version.cpp in Sources */,
+                               020D47A20A16C1E00027E24E /* EncoreBootImageReader.cpp in Sources */,
+                               021240010A6C3AA9003CF33F /* Blob.cpp in Sources */,
+                               021240020A6C3AAA003CF33F /* HexValues.cpp in Sources */,
+                               02C5DB950A925C61003B9C11 /* format_string.cpp in Sources */,
+                               02D1FCF70BD039A0007C7450 /* SearchPath.cpp in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               02E25EA20A1A5DB0001161B5 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               02E25EAA0A1A5DCB001161B5 /* keygen.cpp in Sources */,
+                               02E25EAE0A1A5DF4001161B5 /* AESKey.cpp in Sources */,
+                               02E25EAF0A1A5E09001161B5 /* Random.cpp in Sources */,
+                               02E25EB00A1A5E0C001161B5 /* Logging.cpp in Sources */,
+                               02E25EB10A1A5E18001161B5 /* stdafx.cpp in Sources */,
+                               02E25EB20A1A5E1C001161B5 /* options.cpp in Sources */,
+                               02C5DB960A925C61003B9C11 /* format_string.cpp in Sources */,
+                               025881010CEE47A900681C7E /* HexValues.cpp in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               8DD76F640486A84900D96B5E /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               0215B3D309F424D800EA7C45 /* elftosb_parser.y in Sources */,
+                               0215B3E909F4277100EA7C45 /* elftosb_lexer.l in Sources */,
+                               0296A4E709D9AE9400F80AFF /* elftosb.cpp in Sources */,
+                               0296A4F209D9AE9400F80AFF /* stdafx.cpp in Sources */,
+                               0296A4F309D9AE9400F80AFF /* StELFFile.cpp in Sources */,
+                               0296A4F809D9AE9400F80AFF /* StExecutableImage.cpp in Sources */,
+                               0296A4FE09D9AE9400F80AFF /* StSRecordFile.cpp in Sources */,
+                               02E3998F09F2EFAA0055992A /* rijndael.cpp in Sources */,
+                               02CD157609F543FE00ABE650 /* ElftosbAST.cpp in Sources */,
+                               02CD158909F557D300ABE650 /* ElftosbLexer.cpp in Sources */,
+                               02E9D67609FBFE98006D7279 /* EvalContext.cpp in Sources */,
+                               02F8D41E09FE86FB004CBE69 /* EncoreBootImage.cpp in Sources */,
+                               02F8D4F109FEE91B004CBE69 /* crc.cpp in Sources */,
+                               02F8D54C0A014F5D004CBE69 /* Value.cpp in Sources */,
+                               02F8D5630A0152AB004CBE69 /* SourceFile.cpp in Sources */,
+                               0208BEB30A02D2B800255D31 /* SHA1.cpp in Sources */,
+                               0208BF4D0A03137800255D31 /* Random.cpp in Sources */,
+                               0208BF8C0A03E04800255D31 /* RijndaelCBCMAC.cpp in Sources */,
+                               0208C03F0A0544BA00255D31 /* options.cpp in Sources */,
+                               0208C08C0A05677000255D31 /* AESKey.cpp in Sources */,
+                               0208C28E0A0A4E5F00255D31 /* DataSource.cpp in Sources */,
+                               0208C2900A0A4E5F00255D31 /* Operation.cpp in Sources */,
+                               0208C2920A0A4E5F00255D31 /* DataTarget.cpp in Sources */,
+                               0208C29B0A0A4EE800255D31 /* ConversionController.cpp in Sources */,
+                               024F1D5F0A0BCD7200D21D61 /* SRecordSourceFile.cpp in Sources */,
+                               024F1D630A0BCD8300D21D61 /* ELFSourceFile.cpp in Sources */,
+                               027402E60A0FB00000CF4BE7 /* GlobMatcher.cpp in Sources */,
+                               020D41880A0FF0C20027E24E /* OutputSection.cpp in Sources */,
+                               020D419A0A0FF5BF0027E24E /* BootImageGenerator.cpp in Sources */,
+                               020D41A60A0FF8880027E24E /* Version.cpp in Sources */,
+                               020D41BA0A0FFD140027E24E /* EncoreBootImageGenerator.cpp in Sources */,
+                               020D43A80A14D7E20027E24E /* Logging.cpp in Sources */,
+                               020D45070A1523350027E24E /* GHSSecInfo.cpp in Sources */,
+                               020DDBED0A1D08AD00E1CB49 /* OptionDictionary.cpp in Sources */,
+                               02123F320A6B057E003CF33F /* Blob.cpp in Sources */,
+                               02123F3A0A6B09CF003CF33F /* HexValues.cpp in Sources */,
+                               021CA3F30A8D16960028326F /* ExcludesListMatcher.cpp in Sources */,
+                               02C5DB940A925C61003B9C11 /* format_string.cpp in Sources */,
+                               02B9D4FD0B9A13AE0084CE1F /* SB36xxBootImageGenerator.cpp in Sources */,
+                               02B9D50A0B9A16C10084CE1F /* crypto.cpp in Sources */,
+                               02B9D50B0B9A16C10084CE1F /* St3600IPL.cpp in Sources */,
+                               02B9D50C0B9A16C10084CE1F /* StKeySet.cpp in Sources */,
+                               02B9D50D0B9A16C10084CE1F /* StLFSREncrypter.cpp in Sources */,
+                               02B9D50E0B9A16C10084CE1F /* table.c in Sources */,
+                               02B9D56C0B9B37890084CE1F /* default_rom_key.cpp in Sources */,
+                               02D1FCA90BD02B69007C7450 /* SearchPath.cpp in Sources */,
+                               02E535B50C245AEC00CBD4A5 /* DataSourceImager.cpp in Sources */,
+                               022B4657121763A100A74F96 /* IVTDataSource.cpp in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+               020DDCEA0A1E858D00E1CB49 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 8DD76F620486A84900D96B5E /* elftosb */;
+                       targetProxy = 020DDCE90A1E858D00E1CB49 /* PBXContainerItemProxy */;
+               };
+               020DDCEC0A1E858D00E1CB49 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 020D467A0A16657C0027E24E /* sbtool */;
+                       targetProxy = 020DDCEB0A1E858D00E1CB49 /* PBXContainerItemProxy */;
+               };
+               020DDCEE0A1E858D00E1CB49 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 02E25EA40A1A5DB0001161B5 /* keygen */;
+                       targetProxy = 020DDCED0A1E858D00E1CB49 /* PBXContainerItemProxy */;
+               };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+               020D467F0A1665890027E24E /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = sbtool;
+                               ZERO_LINK = NO;
+                       };
+                       name = Debug;
+               };
+               020D46800A1665890027E24E /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_MODEL_TUNING = G5;
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = sbtool;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               020DDCF10A1E85BA00E1CB49 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               PRODUCT_NAME = Everything;
+                       };
+                       name = Debug;
+               };
+               020DDCF20A1E85BA00E1CB49 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               PRODUCT_NAME = Everything;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               02E25EAC0A1A5DCB001161B5 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = keygen;
+                               ZERO_LINK = YES;
+                       };
+                       name = Debug;
+               };
+               02E25EAD0A1A5DCB001161B5 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_MODEL_TUNING = G5;
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PREBINDING = NO;
+                               PRODUCT_NAME = keygen;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               1DEB923208733DC60010E9CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       SHA1_NO_UTILITY_FUNCTIONS,
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PRODUCT_NAME = elftosb;
+                               ZERO_LINK = NO;
+                       };
+                       name = Debug;
+               };
+               1DEB923308733DC60010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = (
+                                       ppc,
+                                       i386,
+                               );
+                               DEBUG_INFORMATION_FORMAT = dwarf;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       SHA1_NO_UTILITY_FUNCTIONS,
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               INSTALL_PATH = "$(HOME)/bin";
+                               PRODUCT_NAME = elftosb;
+                               ZERO_LINK = NO;
+                       };
+                       name = Release;
+               };
+               1DEB923608733DC60010E9CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               PREBINDING = NO;
+                               SDKROOT = macosx10.5;
+                       };
+                       name = Debug;
+               };
+               1DEB923708733DC60010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               PREBINDING = NO;
+                               SDKROOT = macosx10.5;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               020D467E0A1665890027E24E /* Build configuration list for PBXNativeTarget "sbtool" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               020D467F0A1665890027E24E /* Debug */,
+                               020D46800A1665890027E24E /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               020DDCF00A1E85BA00E1CB49 /* Build configuration list for PBXAggregateTarget "Everything" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               020DDCF10A1E85BA00E1CB49 /* Debug */,
+                               020DDCF20A1E85BA00E1CB49 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               02E25EAB0A1A5DCB001161B5 /* Build configuration list for PBXNativeTarget "keygen" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               02E25EAC0A1A5DCB001161B5 /* Debug */,
+                               02E25EAD0A1A5DCB001161B5 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               1DEB923108733DC60010E9CD /* Build configuration list for PBXNativeTarget "elftosb" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB923208733DC60010E9CD /* Debug */,
+                               1DEB923308733DC60010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "elftosb" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB923608733DC60010E9CD /* Debug */,
+                               1DEB923708733DC60010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/tools/elftosb/elftosb2/BootImageGenerator.cpp b/tools/elftosb/elftosb2/BootImageGenerator.cpp
new file mode 100644 (file)
index 0000000..63daf26
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ *  BootImageGenerator.cpp
+ *  elftosb
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "BootImageGenerator.h"
+#include "Logging.h"
+
+//! Name of product version option.
+#define kProductVersionOption "productVersion"
+
+//! Name of component version option.
+#define kComponentVersionOption "componentVersion"
+
+//! Name of option that specifies the drive tag for this .sb file.
+#define kDriveTagOption "driveTag"
+
+using namespace elftosb;
+
+void BootImageGenerator::processVersionOptions(BootImage * image)
+{
+       // bail if no option context was set
+       if (!m_options)
+       {
+               return;
+       }
+       
+       const StringValue * stringValue;
+       version_t version;
+       
+    // productVersion
+       if (m_options->hasOption(kProductVersionOption))
+       {
+               stringValue = dynamic_cast<const StringValue *>(m_options->getOption(kProductVersionOption));
+               if (stringValue)
+               {
+                       version.set(*stringValue);
+                       image->setProductVersion(version);
+               }
+        else
+        {
+            Log::log(Logger::WARNING, "warning: productVersion option is an unexpected type\n");
+        }
+       }
+       
+    // componentVersion
+       if (m_options->hasOption(kComponentVersionOption))
+       {
+               stringValue = dynamic_cast<const StringValue *>(m_options->getOption(kComponentVersionOption));
+               if (stringValue)
+               {
+                       version.set(*stringValue);
+                       image->setComponentVersion(version);
+               }
+        else
+        {
+            Log::log(Logger::WARNING, "warning: componentVersion option is an unexpected type\n");
+        }
+       }
+}
+
+void BootImageGenerator::processDriveTagOption(BootImage * image)
+{
+       if (m_options->hasOption(kDriveTagOption))
+       {
+               const IntegerValue * intValue = dynamic_cast<const IntegerValue *>(m_options->getOption(kDriveTagOption));
+               if (intValue)
+               {
+                       image->setDriveTag(intValue->getValue());
+               }
+        else
+        {
+            Log::log(Logger::WARNING, "warning: driveTag option is an unexpected type\n");
+        }
+       }
+}
+
diff --git a/tools/elftosb/elftosb2/BootImageGenerator.h b/tools/elftosb/elftosb2/BootImageGenerator.h
new file mode 100644 (file)
index 0000000..3d50fbb
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * File:       BootImageGenerator.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_BootImageGenerator_h_)
+#define _BootImageGenerator_h_
+
+#include "OutputSection.h"
+#include "BootImage.h"
+#include "OptionContext.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Abstract base class for generators of specific boot image formats.
+ *
+ * Subclasses implement a concrete generator for a certain boot image format, but
+ * they all have the same interface.
+ *
+ * After creating an instance of a subclass the user adds OutputSection objects
+ * to the generator. These objects describe discrete sections within the resulting
+ * boot image file. If the format does not support multiple sections then only
+ * the first will be used.
+ *
+ * Options that are common to all boot image formats are handled by methods
+ * defined in this class. These are the current common options:
+ *     - productVersion
+ *     - componentVersion
+ *     - driveTag
+ */
+class BootImageGenerator
+{
+public:
+       //! \brief Constructor.
+       BootImageGenerator() {}
+       
+       //! \brief Destructor.
+       virtual ~BootImageGenerator() {}
+       
+       //! \brief Add another section to the output.
+       void addOutputSection(OutputSection * section) { m_sections.push_back(section); }
+       
+       //! \brief Set the global option context.
+       void setOptionContext(OptionContext * context) { m_options = context; }
+       
+       //! \brief Pure virtual method to generate the output BootImage from input sections.
+       virtual BootImage * generate()=0;
+       
+protected:
+       //! Type for a list of model output sections.
+       typedef std::vector<OutputSection*> section_vector_t;
+       
+       section_vector_t m_sections;    //!< Requested output sections.
+       OptionContext * m_options;      //!< Global option context.
+    
+    //! \brief Handle common product and component version options.
+    void processVersionOptions(BootImage * image);
+       
+       //! \brief Handle the common option which sets the system drive tag.
+       void processDriveTagOption(BootImage * image);
+};
+
+}; // namespace elftosb
+
+#endif // _BootImageGenerator_h_
+
diff --git a/tools/elftosb/elftosb2/ConversionController.cpp b/tools/elftosb/elftosb2/ConversionController.cpp
new file mode 100644 (file)
index 0000000..dd3341c
--- /dev/null
@@ -0,0 +1,1428 @@
+/*
+ * File:       ConversionController.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "ConversionController.h"
+#include <stdexcept>
+#include "EvalContext.h"
+#include "ElftosbErrors.h"
+#include "GlobMatcher.h"
+#include "ExcludesListMatcher.h"
+#include "BootImageGenerator.h"
+#include "EncoreBootImageGenerator.h"
+#include "Logging.h"
+#include "OptionDictionary.h"
+#include "format_string.h"
+#include "SearchPath.h"
+#include "DataSourceImager.h"
+#include "IVTDataSource.h"
+#include <algorithm>
+
+//! Set to 1 to cause the ConversionController to print information about
+//! the values that it processes (options, constants, etc.).
+#define PRINT_VALUES 1
+
+using namespace elftosb;
+
+// Define the parser function prototype;
+extern int yyparse(ElftosbLexer * lexer, CommandFileASTNode ** resultAST);
+
+bool elftosb::g_enableHABSupport = false;
+
+ConversionController::ConversionController()
+:      OptionDictionary(),
+       m_commandFilePath(),
+       m_ast(),
+       m_defaultSource(0)
+{
+       m_context.setSourceFileManager(this);
+}
+
+ConversionController::~ConversionController()
+{
+       // clean up sources
+       source_map_t::iterator it = m_sources.begin();
+       for (; it != m_sources.end(); ++it)
+       {
+               if (it->second)
+               {
+                       delete it->second;
+               }
+       }
+}
+
+void ConversionController::setCommandFilePath(const std::string & path)
+{
+       m_commandFilePath = new std::string(path);
+}
+
+//! The paths provided to this method are added to an array and accessed with the
+//! "extern(N)" notation in the command file. So the path provided in the third
+//! call to addExternalFilePath() will be found with N=2 in the source definition.
+void ConversionController::addExternalFilePath(const std::string & path)
+{
+       m_externPaths.push_back(path);
+}
+
+bool ConversionController::hasSourceFile(const std::string & name)
+{
+       return m_sources.find(name) != m_sources.end();
+}
+
+SourceFile * ConversionController::getSourceFile(const std::string & name)
+{
+       if (!hasSourceFile(name))
+       {
+               return NULL;
+       }
+       
+       return m_sources[name];
+}
+
+SourceFile * ConversionController::getDefaultSourceFile()
+{
+       return m_defaultSource;
+}
+
+//! These steps are executed while running this method:
+//!            - The command file is parsed into an abstract syntax tree.
+//!            - The list of options is extracted.
+//!            - Constant expressions are evaluated.
+//!            - The list of source files is extracted and source file objects created.
+//!            - Section definitions are extracted.
+//!
+//! This method does not produce any output. It processes the input files and
+//! builds a representation of the output in memory. Use the generateOutput() method
+//! to produce a BootImage object after this method returns.
+//!
+//! \note This method is \e not reentrant. And in fact, the whole class is not designed
+//!            to be reentrant.
+//!
+//! \exception std::runtime_error Any number of problems will cause this exception to
+//!            be thrown.
+//!
+//! \see parseCommandFile()
+//! \see processOptions()
+//! \see processConstants()
+//! \see processSources()
+//! \see processSections()
+void ConversionController::run()
+{
+#if PRINT_VALUES
+       Log::SetOutputLevel debugLevel(Logger::DEBUG2);
+#endif
+
+       parseCommandFile();
+       assert(m_ast);
+       
+       ListASTNode * blocks = m_ast->getBlocks();
+       if (!blocks)
+       {
+               throw std::runtime_error("command file has no blocks");
+       }
+       
+       ListASTNode::iterator it = blocks->begin();
+       for (; it != blocks->end(); ++it)
+       {
+               ASTNode * node = *it;
+               
+               // Handle an options block.
+               OptionsBlockASTNode * options = dynamic_cast<OptionsBlockASTNode *>(node);
+               if (options)
+               {
+                       processOptions(options->getOptions());
+                       continue;
+               }
+               
+               // Handle a constants block.
+               ConstantsBlockASTNode * constants = dynamic_cast<ConstantsBlockASTNode *>(node);
+               if (constants)
+               {
+                       processConstants(constants->getConstants());
+                       continue;
+               }
+               
+               // Handle a sources block.
+               SourcesBlockASTNode * sources = dynamic_cast<SourcesBlockASTNode *>(node);
+               if (sources)
+               {
+                       processSources(sources->getSources());
+               }
+       }
+       
+       processSections(m_ast->getSections());
+}
+
+//! Opens the command file and runs it through the lexer and parser. The resulting
+//! abstract syntax tree is held in the m_ast member variable. After parsing, the
+//! command file is closed.
+//!
+//! \exception std::runtime_error Several problems will cause this exception to be
+//!            raised, including an unspecified command file path or an error opening the
+//!            file.
+void ConversionController::parseCommandFile()
+{
+       if (!m_commandFilePath)
+       {
+               throw std::runtime_error("no command file path was provided");
+       }
+       
+       // Search for command file
+       std::string actualPath;
+       bool found = PathSearcher::getGlobalSearcher().search(*m_commandFilePath, PathSearcher::kFindFile, true, actualPath);
+       if (!found)
+       {
+               throw runtime_error(format_string("unable to find command file %s\n", m_commandFilePath->c_str()));
+       }
+
+       // open command file
+       std::ifstream commandFile(actualPath.c_str(), ios_base::in | ios_base::binary);
+       if (!commandFile.is_open())
+       {
+               throw std::runtime_error("could not open command file");
+       }
+       
+       try
+       {
+               // create lexer instance
+               ElftosbLexer lexer(commandFile);
+//             testLexer(lexer);
+               
+               CommandFileASTNode * ast = NULL;
+               int result = yyparse(&lexer, &ast);
+               m_ast = ast;
+               
+               // check results
+               if (result || !m_ast)
+               {
+                       throw std::runtime_error("failed to parse command file");
+               }
+               
+               // dump AST
+//             m_ast->printTree(0);
+               
+               // close command file
+               commandFile.close();
+       }
+       catch (...)
+       {
+               // close command file
+               commandFile.close();
+               
+               // rethrow exception
+               throw;
+       }
+}
+
+//! Iterates over the option definition AST nodes. elftosb::Value objects are created for
+//! each option value and added to the option dictionary.
+//!
+//! \exception std::runtime_error Various errors will cause this exception to be thrown. These
+//!            include AST nodes being an unexpected type or expression not evaluating to integers.
+void ConversionController::processOptions(ListASTNode * options)
+{
+       if (!options)
+       {
+               return;
+       }
+       
+       ListASTNode::iterator it = options->begin();
+       for (; it != options->end(); ++it)
+       {
+               std::string ident;
+               Value * value = convertAssignmentNodeToValue(*it, ident);
+               
+               // check if this option has already been set
+               if (hasOption(ident))
+               {
+                       throw semantic_error(format_string("line %d: option already set", (*it)->getFirstLine()));
+               }
+               
+               // now save the option value in our map
+               if (value)
+               {
+                       setOption(ident, value);
+               }
+       }
+}
+
+//! Scans the constant definition AST nodes, evaluates expression nodes by calling their
+//! elftosb::ExprASTNode::reduce() method, and updates the evaluation context member so
+//! those constant values can be used in other expressions.
+//!
+//! \exception std::runtime_error Various errors will cause this exception to be thrown. These
+//!            include AST nodes being an unexpected type or expression not evaluating to integers.
+void ConversionController::processConstants(ListASTNode * constants)
+{
+       if (!constants)
+       {
+               return;
+       }
+       
+       ListASTNode::iterator it = constants->begin();
+       for (; it != constants->end(); ++it)
+       {
+               std::string ident;
+               Value * value = convertAssignmentNodeToValue(*it, ident);
+               
+               SizedIntegerValue * intValue = dynamic_cast<SizedIntegerValue*>(value);
+               if (!intValue)
+               {
+                       throw semantic_error(format_string("line %d: constant value is an invalid type", (*it)->getFirstLine()));
+               }
+                               
+//#if PRINT_VALUES
+//             Log::log("constant ");
+//             printIntConstExpr(ident, intValue);
+//#endif
+               
+               // record this constant's value in the evaluation context
+               m_context.setVariable(ident, intValue->getValue(), intValue->getWordSize());
+       }
+}
+
+//! \exception std::runtime_error Various errors will cause this exception to be thrown. These
+//!            include AST nodes being an unexpected type or expression not evaluating to integers.
+//!
+//! \todo Handle freeing of dict if an exception occurs.
+void ConversionController::processSources(ListASTNode * sources)
+{
+       if (!sources)
+       {
+               return;
+       }
+       
+       ListASTNode::iterator it = sources->begin();
+       for (; it != sources->end(); ++it)
+       {
+               SourceDefASTNode * node = dynamic_cast<SourceDefASTNode*>(*it);
+               if (!node)
+               {
+                       throw semantic_error(format_string("line %d: source definition node is an unexpected type", node->getFirstLine()));
+               }
+               
+               // get source name and check if it has already been defined
+               std::string * name = node->getName();
+               if (m_sources.find(*name) != m_sources.end())
+               {
+                       // can't define a source multiple times
+                       throw semantic_error(format_string("line %d: source already defined", node->getFirstLine()));
+               }
+               
+               // convert attributes into an option dict
+               OptionDictionary * dict = new OptionDictionary(this);
+               ListASTNode * attrsNode = node->getAttributes();
+               if (attrsNode)
+               {
+                       ListASTNode::iterator attrIt = attrsNode->begin();
+                       for (; attrIt != attrsNode->end(); ++attrIt)
+                       {
+                               std::string ident;
+                               Value * value = convertAssignmentNodeToValue(*attrIt, ident);
+                               dict->setOption(ident, value);
+                       }
+               }
+               
+               // figure out which type of source definition this is
+               PathSourceDefASTNode * pathNode = dynamic_cast<PathSourceDefASTNode*>(node);
+               ExternSourceDefASTNode * externNode = dynamic_cast<ExternSourceDefASTNode*>(node);
+               SourceFile * file = NULL;
+               
+               if (pathNode)
+               {
+                       // explicit path
+                       std::string * path = pathNode->getPath();
+                       
+#if PRINT_VALUES
+                       Log::log("source %s => path(%s)\n", name->c_str(), path->c_str());
+#endif
+                       
+                       try
+                       {
+                               file = SourceFile::openFile(*path);
+                       }
+                       catch (...)
+                       {
+                               // file doesn't exist
+                               Log::log(Logger::INFO2, "failed to open source file: %s (ignoring for now)\n", path->c_str());
+                               m_failedSources.push_back(*name);
+                       }
+               }
+               else if (externNode)
+               {
+                       // externally provided path
+                       ExprASTNode * expr = externNode->getSourceNumberExpr()->reduce(m_context);
+                       IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(expr);
+                       if (!intConst)
+                       {
+                               throw semantic_error(format_string("line %d: expression didn't evaluate to an integer", expr->getFirstLine()));
+                       }
+                       
+                       uint32_t externalFileNumber = static_cast<uint32_t>(intConst->getValue());
+                       
+                       // make sure the extern number is valid
+                       if (externalFileNumber >= 0 && externalFileNumber < m_externPaths.size())
+                       {
+                       
+#if PRINT_VALUES
+                       Log::log("source %s => extern(%d=%s)\n", name->c_str(), externalFileNumber, m_externPaths[externalFileNumber].c_str());
+#endif
+                       
+                               try
+                               {
+                                       file = SourceFile::openFile(m_externPaths[externalFileNumber]);
+                               }
+                               catch (...)
+                               {
+                                       Log::log(Logger::INFO2, "failed to open source file: %s (ignoring for now)\n", m_externPaths[externalFileNumber].c_str());
+                                       m_failedSources.push_back(*name);
+                               }
+                       }
+               }
+               else
+               {
+                       throw semantic_error(format_string("line %d: unexpected source definition node type", node->getFirstLine()));
+               }
+               
+               if (file)
+               {
+                       // set options
+                       file->setOptions(dict);
+                       
+                       // stick the file object in the source map
+                       m_sources[*name] = file;
+               }
+       }
+}
+
+void ConversionController::processSections(ListASTNode * sections)
+{
+       if (!sections)
+       {
+               Log::log(Logger::WARNING, "warning: no sections were defined in command file");
+               return;
+       }
+       
+       ListASTNode::iterator it = sections->begin();
+       for (; it != sections->end(); ++it)
+       {
+               SectionContentsASTNode * node = dynamic_cast<SectionContentsASTNode*>(*it);
+               if (!node)
+               {
+                       throw semantic_error(format_string("line %d: section definition is unexpected type", node->getFirstLine()));
+               }
+               
+               // evaluate section number
+               ExprASTNode * idExpr = node->getSectionNumberExpr()->reduce(m_context);
+               IntConstExprASTNode * idConst = dynamic_cast<IntConstExprASTNode*>(idExpr);
+               if (!idConst)
+               {
+                       throw semantic_error(format_string("line %d: section number did not evaluate to an integer", idExpr->getFirstLine()));
+               }
+               uint32_t sectionID = idConst->getValue();
+               
+               // Create options context for this section. The options context has the
+               // conversion controller as its parent context so it will inherit global options.
+               // The context will be set in the section after the section is created below.
+               OptionDictionary * optionsDict = new OptionDictionary(this);
+               ListASTNode * attrsNode = node->getOptions();
+               if (attrsNode)
+               {
+                       ListASTNode::iterator attrIt = attrsNode->begin();
+                       for (; attrIt != attrsNode->end(); ++attrIt)
+                       {
+                               std::string ident;
+                               Value * value = convertAssignmentNodeToValue(*attrIt, ident);
+                               optionsDict->setOption(ident, value);
+                       }
+               }
+               
+               // Now create the actual section object based on its type.
+               OutputSection * outputSection = NULL;
+               BootableSectionContentsASTNode * bootableSection;
+               DataSectionContentsASTNode * dataSection;
+               if (bootableSection = dynamic_cast<BootableSectionContentsASTNode*>(node))
+               {               
+                       // process statements into a sequence of operations
+                       ListASTNode * statements = bootableSection->getStatements();
+                       OperationSequence * sequence = convertStatementList(statements);
+
+#if 0
+                       Log::log("section ID = %d\n", sectionID);
+                       statements->printTree(0);
+                       
+                       Log::log("sequence has %d operations\n", sequence->getCount());
+                       OperationSequence::iterator_t it = sequence->begin();
+                       for (; it != sequence->end(); ++it)
+                       {
+                               Operation * op = *it;
+                               Log::log("op = %p\n", op);
+                       }
+#endif
+                       
+                       // create the output section and add it to the list
+                       OperationSequenceSection * opSection = new OperationSequenceSection(sectionID);
+                       opSection->setOptions(optionsDict);
+                       opSection->getSequence() += sequence;
+                       outputSection = opSection;
+               }
+               else if (dataSection = dynamic_cast<DataSectionContentsASTNode*>(node))
+               {
+                       outputSection = convertDataSection(dataSection, sectionID, optionsDict);
+               }
+               else
+               {
+                       throw semantic_error(format_string("line %d: unexpected section contents type", node->getFirstLine()));
+               }
+               
+               if (outputSection)
+               {
+                       m_outputSections.push_back(outputSection);
+               }
+       }
+}
+
+//! Creates an instance of BinaryDataSection from the AST node passed in the
+//! \a dataSection parameter. The section-specific options for this node will
+//! have already been converted into an OptionDictionary, the one passed in
+//! the \a optionsDict parameter.
+//!
+//! The \a dataSection node will have as its contents one of the AST node
+//! classes that represents a source of data. The member function
+//! createSourceFromNode() is used to convert this AST node into an
+//! instance of a DataSource subclass. Then the method imageDataSource()
+//! converts the segments of the DataSource into a raw binary buffer that
+//! becomes the contents of the BinaryDataSection this is returned.
+//!
+//! \param dataSection The AST node for the data section.
+//! \param sectionID Unique tag value the user has assigned to this section.
+//! \param optionsDict Options that apply only to this section. This dictionary
+//!            will be assigned as the options dictionary for the resulting section
+//!            object. Its parent is the conversion controller itself.
+//! \return An instance of BinaryDataSection. Its contents are a contiguous
+//!            binary representation of the contents of \a dataSection.
+OutputSection * ConversionController::convertDataSection(DataSectionContentsASTNode * dataSection, uint32_t sectionID, OptionDictionary * optionsDict)
+{
+       // Create a data source from the section contents AST node.
+       ASTNode * contents = dataSection->getContents();
+       DataSource * dataSource = createSourceFromNode(contents);
+       
+       // Convert the data source to a raw buffer.
+       DataSourceImager imager;
+       imager.addDataSource(dataSource);
+       
+       // Then make a data section from the buffer.
+       BinaryDataSection * resultSection = new BinaryDataSection(sectionID);
+       resultSection->setOptions(optionsDict);
+       if (imager.getLength())
+       {
+               resultSection->setData(imager.getData(), imager.getLength());
+       }
+       
+       return resultSection;
+}
+
+//! @param node The AST node instance for the assignment expression.
+//! @param[out] ident Upon exit this string will be set the the left hand side of the
+//!            assignment expression, the identifier name.
+//!
+//! @return An object that is a subclass of Value is returned. The specific subclass will
+//!            depend on the type of the right hand side of the assignment expression whose AST
+//!            node was provided in the @a node argument.
+//!
+//! @exception semantic_error Thrown for any error where an AST node is an unexpected type.
+//!            This may be the @a node argument itself, if it is not an AssignmentASTNode. Or it
+//!            may be an unexpected type for either the right or left hand side of the assignment.
+//!            The message for the exception will contain a description of the error.
+Value * ConversionController::convertAssignmentNodeToValue(ASTNode * node, std::string & ident)
+{
+       Value * resultValue = NULL;
+       
+       // each item of the options list should be an assignment node
+       AssignmentASTNode * assignmentNode = dynamic_cast<AssignmentASTNode*>(node);
+       if (!node)
+       {
+               throw semantic_error(format_string("line %d: node is wrong type", assignmentNode->getFirstLine()));
+       }
+       
+       // save the left hand side (the identifier) into ident
+       ident = *assignmentNode->getIdent();
+       
+       // get the right hand side and convert it to a Value instance
+       ASTNode * valueNode = assignmentNode->getValue();
+       StringConstASTNode * str;
+       ExprASTNode * expr;
+       if (str = dynamic_cast<StringConstASTNode*>(valueNode))
+       {
+               // the option value is a string constant
+               resultValue = new StringValue(str->getString());
+
+//#if PRINT_VALUES
+//             Log::log("option %s => \'%s\'\n", ident->c_str(), str->getString()->c_str());
+//#endif
+       }
+       else if (expr = dynamic_cast<ExprASTNode*>(valueNode))
+       {
+               ExprASTNode * reducedExpr = expr->reduce(m_context);
+               IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(reducedExpr);
+               if (!intConst)
+               {
+                       throw semantic_error(format_string("line %d: expression didn't evaluate to an integer", expr->getFirstLine()));
+               }
+               
+//#if PRINT_VALUES
+//             Log::log("option ");
+//             printIntConstExpr(*ident, intConst);
+//#endif
+               
+               resultValue = new SizedIntegerValue(intConst->getValue(), intConst->getSize());
+       }
+       else
+       {
+               throw semantic_error(format_string("line %d: right hand side node is an unexpected type", valueNode->getFirstLine()));
+       }
+       
+       return resultValue;
+}
+
+//! Builds up a sequence of Operation objects that are equivalent to the
+//! statements in the \a statements list. The statement list is simply iterated
+//! over and the results of convertOneStatement() are used to build up
+//! the final result sequence.
+//!
+//! \see convertOneStatement()
+OperationSequence * ConversionController::convertStatementList(ListASTNode * statements)
+{
+       OperationSequence * resultSequence = new OperationSequence();
+       ListASTNode::iterator it = statements->begin();
+       for (; it != statements->end(); ++it)
+       {
+               StatementASTNode * statement = dynamic_cast<StatementASTNode*>(*it);
+               if (!statement)
+               {
+                       throw semantic_error(format_string("line %d: statement node is unexpected type", (*it)->getFirstLine()));
+               }
+               
+               // convert this statement and append it to the result
+               OperationSequence * sequence = convertOneStatement(statement);
+               if (sequence)
+               {
+                       *resultSequence += sequence;
+               }
+       }
+       
+       return resultSequence;
+}
+
+//! Uses C++ RTTI to identify the particular subclass of StatementASTNode that
+//! the \a statement argument matches. Then the appropriate conversion method
+//! is called.
+//!
+//! \see convertLoadStatement()
+//! \see convertCallStatement()
+//! \see convertFromStatement()
+OperationSequence * ConversionController::convertOneStatement(StatementASTNode * statement)
+{
+       // see if it's a load statement
+       LoadStatementASTNode * load = dynamic_cast<LoadStatementASTNode*>(statement);
+       if (load)
+       {
+               return convertLoadStatement(load);
+       }
+       
+       // see if it's a call statement
+       CallStatementASTNode * call = dynamic_cast<CallStatementASTNode*>(statement);
+       if (call)
+       {
+               return convertCallStatement(call);
+       }
+       
+       // see if it's a from statement
+       FromStatementASTNode * from = dynamic_cast<FromStatementASTNode*>(statement);
+       if (from)
+       {
+               return convertFromStatement(from);
+       }
+       
+       // see if it's a mode statement
+       ModeStatementASTNode * mode = dynamic_cast<ModeStatementASTNode*>(statement);
+       if (mode)
+       {
+               return convertModeStatement(mode);
+       }
+       
+       // see if it's an if statement
+       IfStatementASTNode * ifStmt = dynamic_cast<IfStatementASTNode*>(statement);
+       if (ifStmt)
+       {
+               return convertIfStatement(ifStmt);
+       }
+       
+       // see if it's a message statement
+       MessageStatementASTNode * messageStmt = dynamic_cast<MessageStatementASTNode*>(statement);
+       if (messageStmt)
+       {
+               // Message statements don't produce operation sequences.
+               handleMessageStatement(messageStmt);
+               return NULL;
+       }
+       
+       // didn't match any of the expected statement types
+       throw semantic_error(format_string("line %d: unexpected statement type", statement->getFirstLine()));
+       return NULL;
+}
+
+//! Possible load data node types:
+//! - StringConstASTNode
+//! - ExprASTNode
+//! - SourceASTNode
+//! - SectionMatchListASTNode
+//!
+//! Possible load target node types:
+//! - SymbolASTNode
+//! - NaturalLocationASTNode
+//! - AddressRangeASTNode
+OperationSequence * ConversionController::convertLoadStatement(LoadStatementASTNode * statement)
+{
+       LoadOperation * op = NULL;
+       
+       try
+       {
+               // build load operation from source and target
+               op = new LoadOperation();
+               op->setSource(createSourceFromNode(statement->getData()));
+               op->setTarget(createTargetFromNode(statement->getTarget()));
+               op->setDCDLoad(statement->isDCDLoad());
+               
+               return new OperationSequence(op);
+       }
+       catch (...)
+       {
+               if (op)
+               {
+                       delete op;
+               }
+               throw;
+       }
+}
+
+//! Possible call target node types:
+//! - SymbolASTNode
+//! - ExprASTNode
+//!
+//! Possible call argument node types:
+//! - ExprASTNode
+//! - NULL
+OperationSequence * ConversionController::convertCallStatement(CallStatementASTNode * statement)
+{
+       ExecuteOperation * op = NULL;
+       
+       try
+       {
+               // create operation from AST nodes
+               op = new ExecuteOperation();
+               
+               bool isHAB = statement->isHAB();
+               
+               op->setTarget(createTargetFromNode(statement->getTarget()));
+               
+               // set argument value, which defaults to 0 if no expression was provided
+               uint32_t arg = 0;
+               ASTNode * argNode = statement->getArgument();
+               if (argNode)
+               {
+                       ExprASTNode * argExprNode = dynamic_cast<ExprASTNode*>(argNode);
+                       if (!argExprNode)
+                       {
+                               throw semantic_error(format_string("line %d: call argument is unexpected type", argNode->getFirstLine()));
+                       }
+                       argExprNode = argExprNode->reduce(m_context);
+                       IntConstExprASTNode * intNode = dynamic_cast<IntConstExprASTNode*>(argExprNode);
+                       if (!intNode)
+                       {
+                               throw semantic_error(format_string("line %d: call argument did not evaluate to an integer", argExprNode->getFirstLine()));
+                       }
+                       
+                       arg = intNode->getValue();
+               }
+               op->setArgument(arg);
+               
+               // set call type
+               switch (statement->getCallType())
+               {
+                       case CallStatementASTNode::kCallType:
+                               op->setExecuteType(ExecuteOperation::kCall);
+                               break;
+                       case CallStatementASTNode::kJumpType:
+                               op->setExecuteType(ExecuteOperation::kJump);
+                               break;
+               }
+               
+               // Set the HAB mode flag.
+               op->setIsHAB(isHAB);
+               
+               return new OperationSequence(op);
+       }
+       catch (...)
+       {
+               // delete op and rethrow exception
+               if (op)
+               {
+                       delete op;
+               }
+               throw;
+       }
+}
+
+//! First this method sets the default source to the source identified in
+//! the from statement. Then the statements within the from block are
+//! processed recursively by calling convertStatementList(). The resulting
+//! operation sequence is returned.
+OperationSequence * ConversionController::convertFromStatement(FromStatementASTNode * statement)
+{
+       if (m_defaultSource)
+       {
+               throw semantic_error(format_string("line %d: from statements cannot be nested", statement->getFirstLine()));
+       }
+       
+       // look up source file instance
+       std::string * fromSourceName = statement->getSourceName();
+       assert(fromSourceName);
+       
+       // make sure it's a valid source name
+       source_map_t::iterator sourceIt = m_sources.find(*fromSourceName);
+       if (sourceIt == m_sources.end())
+       {
+               throw semantic_error(format_string("line %d: bad source name", statement->getFirstLine()));
+       }
+       
+       // set default source
+       m_defaultSource = sourceIt->second;
+       assert(m_defaultSource);
+       
+       // get statements inside the from block
+       ListASTNode * fromStatements = statement->getStatements();
+       assert(fromStatements);
+       
+       // produce resulting operation sequence
+       OperationSequence * result = convertStatementList(fromStatements);
+       
+       // restore default source to NULL
+       m_defaultSource = NULL;
+       
+       return result;
+}
+
+//! Evaluates the expression to get the new boot mode value. Then creates a
+//! BootModeOperation object and returns an OperationSequence containing it.
+//!
+//! \exception elftosb::semantic_error Thrown if a semantic problem is found with
+//!            the boot mode expression.
+OperationSequence * ConversionController::convertModeStatement(ModeStatementASTNode * statement)
+{
+       BootModeOperation * op = NULL;
+       
+       try
+       {
+               op = new BootModeOperation();
+               
+               // evaluate the boot mode expression
+               ExprASTNode * modeExprNode = statement->getModeExpr();
+               if (!modeExprNode)
+               {
+                       throw semantic_error(format_string("line %d: mode statement has invalid boot mode expression", statement->getFirstLine()));
+               }
+               modeExprNode = modeExprNode->reduce(m_context);
+               IntConstExprASTNode * intNode = dynamic_cast<IntConstExprASTNode*>(modeExprNode);
+               if (!intNode)
+               {
+                       throw semantic_error(format_string("line %d: boot mode did not evaluate to an integer", statement->getFirstLine()));
+               }
+               
+               op->setBootMode(intNode->getValue());
+               
+               return new OperationSequence(op);
+       }
+       catch (...)
+       {
+               if (op)
+               {
+                       delete op;
+               }
+               
+               // rethrow exception
+               throw;
+       }
+}
+
+//! Else branches, including else-if, are handled recursively, so there is a limit
+//! on the number of them based on the stack size.
+//!
+//! \return Returns the operation sequence for the branch of the if statement that
+//!            evaluated to true. If the statement did not have an else branch and the
+//!            condition expression evaluated to false, then NULL will be returned.
+//!
+//! \todo Handle else branches without recursion.
+OperationSequence * ConversionController::convertIfStatement(IfStatementASTNode * statement)
+{
+       // Get the if's conditional expression.
+       ExprASTNode * conditionalExpr = statement->getConditionExpr();
+       if (!conditionalExpr)
+       {
+               throw semantic_error(format_string("line %d: missing or invalid conditional expression", statement->getFirstLine()));
+       }
+       
+       // Reduce the conditional to a single integer.
+       conditionalExpr = conditionalExpr->reduce(m_context);
+       IntConstExprASTNode * intNode = dynamic_cast<IntConstExprASTNode*>(conditionalExpr);
+       if (!intNode)
+       {
+               throw semantic_error(format_string("line %d: if statement conditional expression did not evaluate to an integer", statement->getFirstLine()));
+       }
+       
+       // Decide which statements to further process by the conditional's boolean value.
+       if (intNode->getValue() && statement->getIfStatements())
+       {
+               return convertStatementList(statement->getIfStatements());
+       }
+       else if (statement->getElseStatements())
+       {
+               return convertStatementList(statement->getElseStatements());
+       }
+       else
+       {
+               // No else branch and the conditional was false, so there are no operations to return.
+               return NULL;
+       }
+}
+
+//! Message statements are executed immediately, by this method. They are
+//! not converted into an abstract operation. All messages are passed through
+//! substituteVariables() before being output.
+//!
+//! \param statement The message statement AST node object.
+void ConversionController::handleMessageStatement(MessageStatementASTNode * statement)
+{
+       string * message = statement->getMessage();
+       if (!message)
+       {
+               throw runtime_error("message statement had no message");
+       }
+       
+       smart_ptr<string> finalMessage = substituteVariables(message);
+       
+       switch (statement->getType())
+       {
+               case MessageStatementASTNode::kInfo:
+                       Log::log(Logger::INFO, "%s\n", finalMessage->c_str());
+                       break;
+               
+               case MessageStatementASTNode::kWarning:
+                       Log::log(Logger::WARNING, "warning: %s\n", finalMessage->c_str());
+                       break;
+               
+               case MessageStatementASTNode::kError:
+                       throw runtime_error(*finalMessage);
+                       break;
+       }
+}
+
+//! Performs shell-like variable substitution on the string passed into it.
+//! Both sources and constants can be substituted. Sources will be replaced
+//! with their path and constants with their integer value. The syntax allows
+//! for some simple formatting for constants.
+//!
+//! The syntax is mostly standard. A substitution begins with a dollar-sign
+//! and is followed by the source or constant name in parentheses. For instance,
+//! "$(mysource)" or "$(myconst)". The parentheses are always required.
+//!
+//! Constant names can be prefixed by a single formatting character followed
+//! by a colon. The only formatting characters currently supported are 'd' for
+//! decimal and 'x' for hex. For example, "$(x:myconst)" will be replaced with
+//! the value of the constant named "myconst" formatted as hexadecimal. The
+//! default is decimal, so the 'd' formatting character isn't really ever
+//! needed.
+//!
+//! \param message The string to perform substitution on.
+//! \return Returns a newly allocated std::string object that has all
+//!            substitutions replaced with the associated value. The caller is
+//!            responsible for freeing the string object using the delete operator.
+std::string * ConversionController::substituteVariables(const std::string * message)
+{
+       string * result = new string();
+       int i;
+       int state = 0;
+       string name;
+       
+       for (i=0; i < message->size(); ++i)
+       {
+               char c = (*message)[i];
+               switch (state)
+               {
+                       case 0:
+                               if (c == '$')
+                               {
+                                       state = 1;
+                               }
+                               else
+                               {
+                                       (*result) += c;
+                               }
+                               break;
+                       
+                       case 1:
+                               if (c == '(')
+                               {
+                                       state = 2;
+                               }
+                               else
+                               {
+                                       // Wasn't a variable substitution, so revert to initial state after
+                                       // inserting the original characters.
+                                       (*result) += '$';
+                                       (*result) += c;
+                                       state = 0;
+                               }
+                               break;
+                       
+                       case 2:
+                               if (c == ')')
+                               {
+                                       // Try the name as a source name first.
+                                       if (m_sources.find(name) != m_sources.end())
+                                       {
+                                               (*result) += m_sources[name]->getPath();
+                                       }
+                                       // Otherwise try it as a variable.
+                                       else
+                                       {
+                                               // Select format.
+                                               const char * fmt = "%d";
+                                               if (name[1] == ':' && (name[0] == 'd' || name[0] == 'x'))
+                                               {
+                                                       if (name[0] == 'x')
+                                                       {
+                                                               fmt = "0x%x";
+                                                       }
+                                                       
+                                                       // Delete the format characters.
+                                                       name.erase(0, 2);
+                                               }
+                                               
+                                               // Now insert the formatted variable if it exists.
+                                               if (m_context.isVariableDefined(name))
+                                               {
+                                                       (*result) += format_string(fmt, m_context.getVariableValue(name));
+                                               }
+                                       }
+                                       
+                                       // Switch back to initial state and clear name.
+                                       state = 0;
+                                       name.clear();
+                               }
+                               else
+                               {
+                                       // Just keep building up the variable name.
+                                       name += c;
+                               }
+                               break;
+               }
+       }
+       
+       return result;
+}
+
+//!
+//! \param generator The generator to use.
+BootImage * ConversionController::generateOutput(BootImageGenerator * generator)
+{
+       // set the generator's option context
+       generator->setOptionContext(this);
+       
+       // add output sections to the generator in sequence
+       section_vector_t::iterator it = m_outputSections.begin();
+       for (; it != m_outputSections.end(); ++it)
+       {
+               generator->addOutputSection(*it);
+       }
+       
+       // and produce the output
+       BootImage * image = generator->generate();
+//     Log::log("boot image = %p\n", image);
+       return image;
+}
+
+//! Takes an AST node that is one of the following subclasses and creates the corresponding
+//! type of DataSource object from it.
+//! - StringConstASTNode
+//! - ExprASTNode
+//! - SourceASTNode
+//! - SectionASTNode
+//! - SectionMatchListASTNode
+//! - BlobConstASTNode
+//! - IVTConstASTNode
+//!
+//! \exception elftosb::semantic_error Thrown if a semantic problem is found with
+//!            the data node.
+//! \exception std::runtime_error Thrown if an error occurs that shouldn't be possible
+//!            based on the grammar.
+DataSource * ConversionController::createSourceFromNode(ASTNode * dataNode)
+{
+       assert(dataNode);
+       
+       DataSource * source = NULL;
+       StringConstASTNode * stringNode;
+       BlobConstASTNode * blobNode;
+       ExprASTNode * exprNode;
+       SourceASTNode * sourceNode;
+       SectionASTNode * sectionNode;
+       SectionMatchListASTNode * matchListNode;
+    IVTConstASTNode * ivtNode;
+       
+       if (stringNode = dynamic_cast<StringConstASTNode*>(dataNode))
+       {
+               // create a data source with the string contents
+               std::string * stringData = stringNode->getString();
+               const uint8_t * stringContents = reinterpret_cast<const uint8_t *>(stringData->c_str());
+               source = new UnmappedDataSource(stringContents, static_cast<unsigned>(stringData->size()));
+       }
+       else if (blobNode = dynamic_cast<BlobConstASTNode*>(dataNode))
+       {
+               // create a data source with the raw binary data
+               Blob * blob = blobNode->getBlob();
+               source = new UnmappedDataSource(blob->getData(), blob->getLength());
+       }
+       else if (exprNode = dynamic_cast<ExprASTNode*>(dataNode))
+       {
+               // reduce the expression first
+               exprNode = exprNode->reduce(m_context);
+               IntConstExprASTNode * intNode = dynamic_cast<IntConstExprASTNode*>(exprNode);
+               if (!intNode)
+               {
+                       throw semantic_error("load pattern expression did not evaluate to an integer");
+               }
+               
+               SizedIntegerValue intValue(intNode->getValue(), intNode->getSize());
+               source = new PatternSource(intValue);
+       }
+       else if (sourceNode = dynamic_cast<SourceASTNode*>(dataNode))
+       {
+               // load the entire source contents
+               SourceFile * sourceFile = getSourceFromName(sourceNode->getSourceName(), sourceNode->getFirstLine());
+               source = sourceFile->createDataSource();
+       }
+       else if (sectionNode = dynamic_cast<SectionASTNode*>(dataNode))
+       {
+               // load some subset of the source
+               SourceFile * sourceFile = getSourceFromName(sectionNode->getSourceName(), sectionNode->getFirstLine());
+               if (!sourceFile->supportsNamedSections())
+               {
+                       throw semantic_error(format_string("line %d: source does not support sections", sectionNode->getFirstLine()));
+               }
+               
+               // create data source from the section name
+               std::string * sectionName = sectionNode->getSectionName();
+               GlobMatcher globber(*sectionName);
+               source = sourceFile->createDataSource(globber);
+               if (!source)
+               {
+                       throw semantic_error(format_string("line %d: no sections match the pattern", sectionNode->getFirstLine()));
+               }
+       }
+       else if (matchListNode = dynamic_cast<SectionMatchListASTNode*>(dataNode))
+       {
+               SourceFile * sourceFile = getSourceFromName(matchListNode->getSourceName(), matchListNode->getFirstLine());
+               if (!sourceFile->supportsNamedSections())
+               {
+                       throw semantic_error(format_string("line %d: source type does not support sections", matchListNode->getFirstLine()));
+               }
+               
+               // create string matcher
+               ExcludesListMatcher matcher;
+               
+               // add each pattern to the matcher
+               ListASTNode * matchList = matchListNode->getSections();
+               ListASTNode::iterator it = matchList->begin();
+               for (; it != matchList->end(); ++it)
+               {
+                       ASTNode * node = *it;
+                       sectionNode = dynamic_cast<SectionASTNode*>(node);
+                       if (!sectionNode)
+                       {
+                               throw std::runtime_error(format_string("line %d: unexpected node type in section pattern list", (*it)->getFirstLine()));
+                       }
+                       bool isInclude = sectionNode->getAction() == SectionASTNode::kInclude;
+                       matcher.addPattern(isInclude, *(sectionNode->getSectionName()));
+               }
+               
+               // create data source from the section match list
+               source = sourceFile->createDataSource(matcher);
+               if (!source)
+               {
+                       throw semantic_error(format_string("line %d: no sections match the section pattern list", matchListNode->getFirstLine()));
+               }
+       }
+    else if (ivtNode = dynamic_cast<IVTConstASTNode*>(dataNode))
+    {
+        source = createIVTDataSource(ivtNode);
+    }
+       else
+       {
+               throw semantic_error(format_string("line %d: unexpected load data node type", dataNode->getFirstLine()));
+       }
+       
+       return source;
+}
+
+DataSource * ConversionController::createIVTDataSource(IVTConstASTNode * ivtNode)
+{
+    IVTDataSource * source = new IVTDataSource;
+    
+    // Iterate over the assignment statements in the IVT definition.
+    ListASTNode * fieldList = ivtNode->getFieldAssignments();
+    
+    if (fieldList)
+    {
+        ListASTNode::iterator it = fieldList->begin();
+        for (; it != fieldList->end(); ++it)
+        {
+            AssignmentASTNode * assignmentNode = dynamic_cast<AssignmentASTNode*>(*it);
+            if (!assignmentNode)
+            {
+                throw std::runtime_error(format_string("line %d: unexpected node type in IVT definition", (*it)->getFirstLine()));
+            }
+            
+            // Get the IVT field name.
+            std::string * fieldName = assignmentNode->getIdent();
+            
+            // Reduce the field expression and get the integer result.
+            ASTNode * valueNode = assignmentNode->getValue();
+            ExprASTNode * valueExpr = dynamic_cast<ExprASTNode*>(valueNode);
+            if (!valueExpr)
+            {
+                throw semantic_error("IVT field must have a valid expression");
+            }
+            IntConstExprASTNode * valueIntExpr = dynamic_cast<IntConstExprASTNode*>(valueExpr->reduce(m_context));
+            if (!valueIntExpr)
+            {
+                throw semantic_error(format_string("line %d: IVT field '%s' does not evaluate to an integer", valueNode->getFirstLine(), fieldName->c_str()));
+            }
+            uint32_t value = static_cast<uint32_t>(valueIntExpr->getValue());
+            
+            // Set the field in the IVT data source.
+            if (!source->setFieldByName(*fieldName, value))
+            {
+                throw semantic_error(format_string("line %d: unknown IVT field '%s'", assignmentNode->getFirstLine(), fieldName->c_str()));
+            }
+        }
+    }
+    
+    return source;
+}
+
+//! Takes an AST node subclass and returns an appropriate DataTarget object that contains
+//! the same information. Supported AST node types are:
+//! - SymbolASTNode
+//! - NaturalLocationASTNode
+//! - AddressRangeASTNode
+//!
+//! \exception elftosb::semantic_error Thrown if a semantic problem is found with
+//!            the target node.
+DataTarget * ConversionController::createTargetFromNode(ASTNode * targetNode)
+{
+       assert(targetNode);
+       
+       DataTarget * target = NULL;
+       SymbolASTNode * symbolNode;
+       NaturalLocationASTNode * naturalNode;
+       AddressRangeASTNode * addressNode;
+       
+       if (symbolNode = dynamic_cast<SymbolASTNode*>(targetNode))
+       {
+               SourceFile * sourceFile = getSourceFromName(symbolNode->getSource(), symbolNode->getFirstLine());
+               std::string * symbolName = symbolNode->getSymbolName();
+               
+               // symbol name is optional
+               if (symbolName)
+               {
+                       if (!sourceFile->supportsNamedSymbols())
+                       {
+                               throw std::runtime_error(format_string("line %d: source does not support symbols", symbolNode->getFirstLine()));
+                       }
+                       
+                       target = sourceFile->createDataTargetForSymbol(*symbolName);
+                       if (!target)
+                       {
+                               throw std::runtime_error(format_string("line %d: source does not have a symbol with that name", symbolNode->getFirstLine()));
+                       }
+               }
+               else
+               {
+                       // no symbol name was specified so use entry point
+                       target = sourceFile->createDataTargetForEntryPoint();
+                       if (!target)
+                       {
+                               throw std::runtime_error(format_string("line %d: source does not have an entry point", symbolNode->getFirstLine()));
+                       }
+               }
+       }
+       else if (naturalNode = dynamic_cast<NaturalLocationASTNode*>(targetNode))
+       {
+               // the target is the source's natural location
+               target = new NaturalDataTarget();
+       }
+       else if (addressNode = dynamic_cast<AddressRangeASTNode*>(targetNode))
+       {
+               // evaluate begin address
+               ExprASTNode * beginExpr = dynamic_cast<ExprASTNode*>(addressNode->getBegin());
+               if (!beginExpr)
+               {
+                       throw semantic_error("address range must always have a beginning expression");
+               }
+               IntConstExprASTNode * beginIntExpr = dynamic_cast<IntConstExprASTNode*>(beginExpr->reduce(m_context));
+               if (!beginIntExpr)
+               {
+                       throw semantic_error("address range begin did not evaluate to an integer");
+               }
+               uint32_t beginAddress = static_cast<uint32_t>(beginIntExpr->getValue());
+               
+               // evaluate end address
+               ExprASTNode * endExpr = dynamic_cast<ExprASTNode*>(addressNode->getEnd());
+               uint32_t endAddress = 0;
+               bool hasEndAddress = false;
+               if (endExpr)
+               {
+                       IntConstExprASTNode * endIntExpr = dynamic_cast<IntConstExprASTNode*>(endExpr->reduce(m_context));
+                       if (!endIntExpr)
+                       {
+                               throw semantic_error("address range end did not evaluate to an integer");
+                       }
+                       endAddress = static_cast<uint32_t>(endIntExpr->getValue());
+                       hasEndAddress = true;
+               }
+               
+               // create target
+               if (hasEndAddress)
+               {
+                       target = new ConstantDataTarget(beginAddress, endAddress);
+               }
+               else
+               {
+                       target = new ConstantDataTarget(beginAddress);
+               }
+       }
+       else
+       {
+               throw semantic_error("unexpected load target node type");
+       }
+       
+       return target;
+}
+
+//! \param sourceName Pointer to string containing the name of the source to look up.
+//!            May be NULL, in which case the default source is used.
+//! \param line The line number on which the source name was located.
+//!
+//! \result A source file object that was previously created in the processSources()
+//!            stage.
+//!
+//! \exception std::runtime_error Thrown if the source name is invalid, or if it
+//!            was NULL and there is no default source (i.e., we're not inside a from
+//!            statement).
+SourceFile * ConversionController::getSourceFromName(std::string * sourceName, int line)
+{
+       SourceFile * sourceFile = NULL;
+       if (sourceName)
+       {
+               // look up source in map
+               source_map_t::iterator it = m_sources.find(*sourceName);
+               if (it == m_sources.end())
+               {
+                       source_name_vector_t::const_iterator findIt = std::find<source_name_vector_t::const_iterator, std::string>(m_failedSources.begin(), m_failedSources.end(), *sourceName);
+                       if (findIt != m_failedSources.end())
+                       {
+                               throw semantic_error(format_string("line %d: error opening source '%s'", line, sourceName->c_str()));
+                       }
+                       else
+                       {
+                               throw semantic_error(format_string("line %d: invalid source name '%s'", line, sourceName->c_str()));
+                       }
+               }
+               sourceFile = it->second;
+       }
+       else
+       {
+               // no name provided - use default source
+               sourceFile = m_defaultSource;
+               if (!sourceFile)
+               {
+                       throw semantic_error(format_string("line %d: source required but no default source is available", line));
+               }
+       }
+       
+       // open the file if it hasn't already been
+       if (!sourceFile->isOpen())
+       {
+               sourceFile->open();
+       }
+       return sourceFile;
+}
+
+//! Exercises the lexer by printing out the value of every token produced by the
+//! lexer. It is assumed that the lexer object has already be configured to read
+//! from some input file. The method will return when the lexer has exhausted all
+//! tokens, or an error occurs.
+void ConversionController::testLexer(ElftosbLexer & lexer)
+{
+       // test lexer
+       while (1)
+       {
+               YYSTYPE value;
+               int lexresult = lexer.yylex();
+               if (lexresult == 0)
+                       break;
+               lexer.getSymbolValue(&value);
+               Log::log("%d -> int:%d, ast:%p", lexresult, value.m_int, value.m_str, value.m_ast);
+               if (lexresult == TOK_IDENT || lexresult == TOK_SOURCE_NAME || lexresult == TOK_STRING_LITERAL)
+               {
+                       if (value.m_str)
+                       {
+                               Log::log(", str:%s\n", value.m_str->c_str());
+                       }
+                       else
+                       {
+                               Log::log("str:NULL\n");
+                       }
+               }
+               else
+               {
+                       Log::log("\n");
+               }
+       }
+}
+
+//! Prints out the value of an integer constant expression AST node. Also prints
+//! the name of the identifier associated with that node, as well as the integer
+//! size.
+void ConversionController::printIntConstExpr(const std::string & ident, IntConstExprASTNode * expr)
+{
+       // print constant value
+       char sizeChar;
+       switch (expr->getSize())
+       {
+               case kWordSize:
+                       sizeChar = 'w';
+                       break;
+               case kHalfWordSize:
+                       sizeChar = 'h';
+                       break;
+               case kByteSize:
+                       sizeChar = 'b';
+                       break;
+       }
+       Log::log("%s => %d:%c\n", ident.c_str(), expr->getValue(), sizeChar);
+}
+
diff --git a/tools/elftosb/elftosb2/ConversionController.h b/tools/elftosb/elftosb2/ConversionController.h
new file mode 100644 (file)
index 0000000..16ae247
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * File:       ConversionController.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_ConversionController_h_)
+#define _ConversionController_h_
+
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <stdexcept>
+#include <smart_ptr.h>
+#include <ElftosbLexer.h>
+#include <ElftosbAST.h>
+#include "EvalContext.h"
+#include "Value.h"
+#include "SourceFile.h"
+#include "Operation.h"
+#include "DataSource.h"
+#include "DataTarget.h"
+#include "OutputSection.h"
+#include "BootImage.h"
+#include "OptionDictionary.h"
+#include "BootImageGenerator.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Manages the entire elftosb file conversion process.
+ *
+ * Instances of this class are intended to be used only once. There is no
+ * way to reset an instance once it has started or completed a conversion.
+ * Thus the run() method is not reentrant. State information is stored in
+ * the object during the conversion process.
+ *
+ * Two things need to be done before the conversion can be started. The
+ * command file path has to be set with the setCommandFilePath() method,
+ * and the paths of any externally provided (i.e., from the command line)
+ * files need to be added with addExternalFilePath(). Once these tasks
+ * are completed, the run() method can be called to parse and execute the
+ * command file. After run() returns, pass an instance of 
+ * BootImageGenerator to the generateOutput() method in order to get
+ * an instance of BootImage that can be written to the output file.
+ */
+class ConversionController : public OptionDictionary, public EvalContext::SourceFileManager
+{
+public:
+       //! \brief Default constructor.
+       ConversionController();
+       
+       //! \brief Destructor.
+       virtual ~ConversionController();
+       
+       //! \name Paths
+       //@{
+       //! \brief Specify the command file that controls the conversion process.
+       void setCommandFilePath(const std::string & path);
+       
+       //! \brief Specify the path of a file provided by the user from outside the command file.
+       void addExternalFilePath(const std::string & path);
+       //@}
+       
+       //! \name Conversion
+       //@{
+       //! \brief Process input files.
+       void run();
+       
+       //! \brief Uses a BootImageGenerator object to create the final output boot image.
+       BootImage * generateOutput(BootImageGenerator * generator);
+       //@}
+       
+       //! \name SourceFileManager interface
+       //@{
+       //! \brief Returns true if a source file with the name \a name exists.
+       virtual bool hasSourceFile(const std::string & name);
+               
+       //! \brief Gets the requested source file.
+       virtual SourceFile * getSourceFile(const std::string & name);
+       
+       //! \brief Returns the default source file, or NULL if none is set.
+       virtual SourceFile * getDefaultSourceFile();
+       //@}
+       
+       //! \brief Returns a reference to the context used for expression evaluation.
+       inline EvalContext & getEvalContext() { return m_context; }
+
+protected:     
+       //! \name AST processing
+       //@{
+       void parseCommandFile();
+       void processOptions(ListASTNode * options);
+       void processConstants(ListASTNode * constants);
+       void processSources(ListASTNode * sources);
+       void processSections(ListASTNode * sections);
+       OutputSection * convertDataSection(DataSectionContentsASTNode * dataSection, uint32_t sectionID, OptionDictionary * optionsDict);
+       //@}
+       
+       //! \name Statement conversion
+       //@{
+       OperationSequence * convertStatementList(ListASTNode * statements);
+       OperationSequence * convertOneStatement(StatementASTNode * statement);
+       OperationSequence * convertLoadStatement(LoadStatementASTNode * statement);
+       OperationSequence * convertCallStatement(CallStatementASTNode * statement);
+       OperationSequence * convertFromStatement(FromStatementASTNode * statement);
+       OperationSequence * convertModeStatement(ModeStatementASTNode * statement);
+       OperationSequence * convertIfStatement(IfStatementASTNode * statement);
+       void handleMessageStatement(MessageStatementASTNode * statement);
+       //@}
+       
+       //! \name Utilities
+       //@{
+       Value * convertAssignmentNodeToValue(ASTNode * node, std::string & ident);
+       SourceFile * getSourceFromName(std::string * sourceName, int line);
+       DataSource * createSourceFromNode(ASTNode * dataNode);
+       DataTarget * createTargetFromNode(ASTNode * targetNode);
+       std::string * substituteVariables(const std::string * message);
+    DataSource * createIVTDataSource(IVTConstASTNode * ivtNode);
+       //@}
+       
+       //! \name Debugging
+       //@{
+       void testLexer(ElftosbLexer & lexer);
+       void printIntConstExpr(const std::string & ident, IntConstExprASTNode * expr);
+       //@}
+
+protected:
+       typedef std::map<std::string, SourceFile*> source_map_t;        //!< Map from source name to object.
+       typedef std::vector<std::string> path_vector_t; //!< List of file paths.
+       typedef std::vector<OutputSection*> section_vector_t;   //!< List of output sections.
+       typedef std::vector<std::string> source_name_vector_t;  //!< List of source names.
+       
+       smart_ptr<std::string> m_commandFilePath;       //!< Path to command file.
+       smart_ptr<CommandFileASTNode> m_ast;    //!< Root of the abstract syntax tree.
+       EvalContext m_context;  //!< Evaluation context for expressions.
+       source_map_t m_sources; //!< Map of source names to file objects.
+       path_vector_t m_externPaths;    //!< Paths provided on the command line by the user.
+       SourceFile * m_defaultSource;   //!< Source to use when one isn't provided.
+       section_vector_t m_outputSections;      //!< List of output sections the user wants.
+       source_name_vector_t m_failedSources;   //!< List of sources that failed to open successfully.
+};
+
+//! \brief Whether to support HAB keywords during parsing.
+//!
+//! This is a standalone global solely so that the bison-generated parser code can get to it
+//! as simply as possible.
+extern bool g_enableHABSupport;
+
+}; // namespace elftosb
+
+#endif // _ConversionController_h_
diff --git a/tools/elftosb/elftosb2/Doxyfile b/tools/elftosb/elftosb2/Doxyfile
new file mode 100644 (file)
index 0000000..6e7f239
--- /dev/null
@@ -0,0 +1,250 @@
+# Doxyfile 1.3.9
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = elftosb
+PROJECT_NUMBER         = 2.0
+OUTPUT_DIRECTORY       = .
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = "/Users/creed/projects/elftosb/elftosb2" \
+                                                "/Users/creed/projects/sgtl/elftosb/sbtool" \
+                                                "/Users/creed/projects/elftosb/common" \
+                                                "/Users/creed/projects/sgtl/elftosb/common"
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 4
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = NO
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = . ../common
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm
+RECURSIVE              = NO
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+VERBATIM_HEADERS       = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/tools/elftosb/elftosb2/ElftosbAST.cpp b/tools/elftosb/elftosb2/ElftosbAST.cpp
new file mode 100644 (file)
index 0000000..ab7732b
--- /dev/null
@@ -0,0 +1,1352 @@
+/*
+ * File:       ElftosbAST.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "ElftosbAST.h"
+#include <stdexcept>
+#include <math.h>
+#include <assert.h>
+#include "ElftosbErrors.h"
+#include "format_string.h"
+
+using namespace elftosb;
+
+#pragma mark = ASTNode =
+
+void ASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       printf("%s\n", nodeName().c_str());
+}
+
+void ASTNode::printIndent(int indent) const
+{
+       int i;
+       for (i=0; i<indent; ++i)
+       {
+               printf("   ");
+       }
+}
+
+void ASTNode::setLocation(token_loc_t & first, token_loc_t & last)
+{
+       m_location.m_firstLine = first.m_firstLine;
+       m_location.m_lastLine = last.m_lastLine;
+}
+
+void ASTNode::setLocation(ASTNode * first, ASTNode * last)
+{
+       m_location.m_firstLine = first->getLocation().m_firstLine;
+       m_location.m_lastLine = last->getLocation().m_lastLine;
+}
+
+#pragma mark = ListASTNode =
+
+ListASTNode::ListASTNode(const ListASTNode & other)
+:      ASTNode(other), m_list()
+{
+       // deep copy each item of the original's list
+       const_iterator it = other.begin();
+       for (; it != other.end(); ++it)
+       {
+               m_list.push_back((*it)->clone());
+       }
+}
+
+//! Deletes child node in the list.
+//!
+ListASTNode::~ListASTNode()
+{
+       iterator it = begin();
+       for (; it != end(); it++)
+       {
+               delete *it;
+       }
+}
+
+//! If \a node is NULL then the list is left unmodified.
+//!
+//! The list node's location is automatically updated after the node is added by a call
+//! to updateLocation().
+void ListASTNode::appendNode(ASTNode * node)
+{
+       if (node)
+       {
+               m_list.push_back(node);
+               updateLocation();
+       }
+}
+
+void ListASTNode::printTree(int indent) const
+{
+       ASTNode::printTree(indent);
+       
+       int n = 0;
+       const_iterator it = begin();
+       for (; it != end(); it++, n++)
+       {
+               printIndent(indent + 1);
+               printf("%d:\n", n);
+               (*it)->printTree(indent + 2);
+       }
+}
+
+void ListASTNode::updateLocation()
+{
+       token_loc_t current = { 0 };
+       const_iterator it = begin();
+       for (; it != end(); it++)
+       {
+               const ASTNode * node = *it;
+               const token_loc_t & loc = node->getLocation();
+               
+               // handle first node
+               if (current.m_firstLine == 0)
+               {
+                       current = loc;
+                       continue;
+               }
+
+               if (loc.m_firstLine < current.m_firstLine)
+               {
+                       current.m_firstLine = loc.m_firstLine;
+               }
+               
+               if (loc.m_lastLine > current.m_lastLine)
+               {
+                       current.m_lastLine = loc.m_lastLine;
+               }
+       }
+       
+       setLocation(current);
+}
+
+#pragma mark = CommandFileASTNode =
+
+CommandFileASTNode::CommandFileASTNode()
+:      ASTNode(), m_options(), m_constants(), m_sources(), m_sections()
+{
+}
+
+CommandFileASTNode::CommandFileASTNode(const CommandFileASTNode & other)
+:      ASTNode(other), m_options(), m_constants(), m_sources(), m_sections()
+{
+       m_options = dynamic_cast<ListASTNode*>(other.m_options->clone());
+       m_constants = dynamic_cast<ListASTNode*>(other.m_constants->clone());
+       m_sources = dynamic_cast<ListASTNode*>(other.m_sources->clone());
+       m_sections = dynamic_cast<ListASTNode*>(other.m_sections->clone());
+}
+
+void CommandFileASTNode::printTree(int indent) const
+{
+       ASTNode::printTree(indent);
+       
+       printIndent(indent + 1);
+       printf("options:\n");
+       if (m_options) m_options->printTree(indent + 2);
+       
+       printIndent(indent + 1);
+       printf("constants:\n");
+       if (m_constants) m_constants->printTree(indent + 2);
+       
+       printIndent(indent + 1);
+       printf("sources:\n");
+       if (m_sources) m_sources->printTree(indent + 2);
+       
+       printIndent(indent + 1);
+       printf("sections:\n");
+       if (m_sections) m_sections->printTree(indent + 2);
+}
+
+#pragma mark = ExprASTNode =
+
+int_size_t ExprASTNode::resultIntSize(int_size_t a, int_size_t b)
+{
+       int_size_t result;
+       switch (a)
+       {
+               case kWordSize:
+                       result = kWordSize;
+                       break;
+               case kHalfWordSize:
+                       if (b == kWordSize)
+                       {
+                               result = kWordSize;
+                       }
+                       else
+                       {
+                               result = kHalfWordSize;
+                       }
+                       break;
+               case kByteSize:
+                       if (b == kWordSize)
+                       {
+                               result = kWordSize;
+                       }
+                       else if (b == kHalfWordSize)
+                       {
+                               result = kHalfWordSize;
+                       }
+                       else
+                       {
+                               result = kByteSize;
+                       }
+                       break;
+       }
+       
+       return result;
+}
+
+#pragma mark = IntConstExprASTNode =
+
+IntConstExprASTNode::IntConstExprASTNode(const IntConstExprASTNode & other)
+:      ExprASTNode(other), m_value(other.m_value), m_size(other.m_size)
+{
+}
+
+void IntConstExprASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       char sizeChar='?';
+       switch (m_size)
+       {
+               case kWordSize:
+                       sizeChar = 'w';
+                       break;
+               case kHalfWordSize:
+                       sizeChar = 'h';
+                       break;
+               case kByteSize:
+                       sizeChar = 'b';
+                       break;
+       }
+       printf("%s(%d:%c)\n", nodeName().c_str(), m_value, sizeChar);
+}
+
+#pragma mark = VariableExprASTNode =
+
+VariableExprASTNode::VariableExprASTNode(const VariableExprASTNode & other)
+:      ExprASTNode(other), m_variable()
+{
+       m_variable = new std::string(*other.m_variable);
+}
+
+void VariableExprASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       printf("%s(%s)\n", nodeName().c_str(), m_variable->c_str());
+}
+
+ExprASTNode * VariableExprASTNode::reduce(EvalContext & context)
+{
+       if (!context.isVariableDefined(*m_variable))
+       {
+               throw std::runtime_error(format_string("line %d: undefined variable '%s'", getFirstLine(), m_variable->c_str()));
+       }
+       
+       uint32_t value = context.getVariableValue(*m_variable);
+       int_size_t size = context.getVariableSize(*m_variable);
+       return new IntConstExprASTNode(value, size);
+}
+
+#pragma mark = SymbolRefExprASTNode =
+
+SymbolRefExprASTNode::SymbolRefExprASTNode(const SymbolRefExprASTNode & other)
+:      ExprASTNode(other), m_symbol(NULL)
+{
+       if (other.m_symbol)
+       {
+               m_symbol = dynamic_cast<SymbolASTNode*>(other.m_symbol->clone());
+       }
+}
+
+void SymbolRefExprASTNode::printTree(int indent) const
+{
+}
+
+ExprASTNode * SymbolRefExprASTNode::reduce(EvalContext & context)
+{
+       EvalContext::SourceFileManager * manager = context.getSourceFileManager();
+       if (!manager)
+       {
+               throw std::runtime_error("no source manager available");
+       }
+       
+       if (!m_symbol)
+       {
+               throw semantic_error("no symbol provided");
+       }
+       
+       // Get the name of the symbol
+       std::string * symbolName = m_symbol->getSymbolName();
+//     if (!symbolName)
+//     {
+//             throw semantic_error(format_string("line %d: no symbol name provided", getFirstLine()));
+//     }
+       
+       // Get the source file.
+       std::string * sourceName = m_symbol->getSource();
+       SourceFile * sourceFile;
+       
+       if (sourceName)
+       {
+               sourceFile = manager->getSourceFile(*sourceName);
+               if (!sourceFile)
+               {
+                       throw semantic_error(format_string("line %d: no source file named %s", getFirstLine(), sourceName->c_str()));
+               }
+       }
+       else
+       {
+               sourceFile = manager->getDefaultSourceFile();
+               if (!sourceFile)
+               {
+                       throw semantic_error(format_string("line %d: no default source file is set", getFirstLine()));
+               }
+       }
+       
+       // open the file if it hasn't already been
+       if (!sourceFile->isOpen())
+       {
+               sourceFile->open();
+       }
+       
+       // Make sure the source file supports symbols before going any further
+       if (symbolName && !sourceFile->supportsNamedSymbols())
+       {
+               throw semantic_error(format_string("line %d: source file %s does not support symbols", getFirstLine(), sourceFile->getPath().c_str()));
+       }
+    
+    if (!symbolName && !sourceFile->hasEntryPoint())
+    {
+        throw semantic_error(format_string("line %d: source file %s does not have an entry point", getFirstLine(), sourceFile->getPath().c_str()));
+    }
+       
+       // Returns a const expr node with the symbol's value.
+       uint32_t value;
+    if (symbolName)
+    {
+        value = sourceFile->getSymbolValue(*symbolName);
+    }
+    else
+    {
+        value = sourceFile->getEntryPointAddress();
+    }
+       return new IntConstExprASTNode(value);
+}
+
+#pragma mark = NegativeExprASTNode =
+
+NegativeExprASTNode::NegativeExprASTNode(const NegativeExprASTNode & other)
+:      ExprASTNode(other), m_expr()
+{
+       m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
+}
+
+void NegativeExprASTNode::printTree(int indent) const
+{
+       ExprASTNode::printTree(indent);
+       if (m_expr) m_expr->printTree(indent + 1);
+}
+
+ExprASTNode * NegativeExprASTNode::reduce(EvalContext & context)
+{
+       if (!m_expr)
+       {
+               return this;
+       }
+       
+       m_expr = m_expr->reduce(context);
+       IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get());
+       if (intConst)
+       {
+           int32_t value = -(int32_t)intConst->getValue();
+               return new IntConstExprASTNode((uint32_t)value, intConst->getSize());
+       }
+       else
+       {
+               return this;
+       }
+}
+
+#pragma mark = BooleanNotExprASTNode =
+
+BooleanNotExprASTNode::BooleanNotExprASTNode(const BooleanNotExprASTNode & other)
+:      ExprASTNode(other), m_expr()
+{
+       m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
+}
+
+void BooleanNotExprASTNode::printTree(int indent) const
+{
+       ExprASTNode::printTree(indent);
+       if (m_expr) m_expr->printTree(indent + 1);
+}
+
+ExprASTNode * BooleanNotExprASTNode::reduce(EvalContext & context)
+{
+       if (!m_expr)
+       {
+               return this;
+       }
+       
+       m_expr = m_expr->reduce(context);
+       IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get());
+       if (intConst)
+       {
+           int32_t value = !((int32_t)intConst->getValue());
+               return new IntConstExprASTNode((uint32_t)value, intConst->getSize());
+       }
+       else
+       {
+               throw semantic_error(format_string("line %d: expression did not evaluate to an integer", m_expr->getFirstLine()));
+       }
+}
+
+#pragma mark = SourceFileFunctionASTNode =
+
+SourceFileFunctionASTNode::SourceFileFunctionASTNode(const SourceFileFunctionASTNode & other)
+:      ExprASTNode(other), m_functionName(), m_sourceFile()
+{
+       m_functionName = new std::string(*other.m_functionName);
+       m_sourceFile = new std::string(*other.m_sourceFile);
+}
+
+void SourceFileFunctionASTNode::printTree(int indent) const
+{
+       ExprASTNode::printTree(indent);
+       printIndent(indent+1);
+
+       // for some stupid reason the msft C++ compiler barfs on the following line if the ".get()" parts are remove,
+       // even though the first line of reduce() below has the same expression, just in parentheses. stupid compiler.
+       if (m_functionName.get() && m_sourceFile.get())
+       {
+               printf("%s ( %s )\n", m_functionName->c_str(), m_sourceFile->c_str());
+       }
+}
+
+ExprASTNode * SourceFileFunctionASTNode::reduce(EvalContext & context)
+{
+       if (!(m_functionName && m_sourceFile))
+       {
+               throw std::runtime_error("unset function name or source file");
+       }
+       
+       // Get source file manager from evaluation context. This will be the
+       // conversion controller itself.
+       EvalContext::SourceFileManager * mgr = context.getSourceFileManager();
+       if (!mgr)
+       {
+               throw std::runtime_error("source file manager is not set");
+       }
+       
+       // Perform function
+       uint32_t functionResult = 0;
+       if (*m_functionName == "exists")
+       {
+               functionResult = static_cast<uint32_t>(mgr->hasSourceFile(*m_sourceFile));
+       }
+       
+       // Return function result as an expression node
+       return new IntConstExprASTNode(functionResult);
+}
+
+#pragma mark = DefinedOperatorASTNode =
+
+DefinedOperatorASTNode::DefinedOperatorASTNode(const DefinedOperatorASTNode & other)
+:      ExprASTNode(other), m_constantName()
+{
+       m_constantName = new std::string(*other.m_constantName);
+}
+
+void DefinedOperatorASTNode::printTree(int indent) const
+{
+       ExprASTNode::printTree(indent);
+       printIndent(indent+1);
+
+       if (m_constantName)
+       {
+               printf("defined ( %s )\n", m_constantName->c_str());
+       }
+}
+
+ExprASTNode * DefinedOperatorASTNode::reduce(EvalContext & context)
+{
+       assert(m_constantName);
+       
+       // Return function result as an expression node
+       return new IntConstExprASTNode(context.isVariableDefined(m_constantName) ? 1 : 0);
+}
+
+#pragma mark = SizeofOperatorASTNode =
+
+SizeofOperatorASTNode::SizeofOperatorASTNode(const SizeofOperatorASTNode & other)
+:      ExprASTNode(other), m_constantName(), m_symbol()
+{
+       m_constantName = new std::string(*other.m_constantName);
+       m_symbol = dynamic_cast<SymbolASTNode*>(other.m_symbol->clone());
+}
+
+void SizeofOperatorASTNode::printTree(int indent) const
+{
+       ExprASTNode::printTree(indent);
+       
+       printIndent(indent+1);
+
+       if (m_constantName)
+       {
+               printf("sizeof: %s\n", m_constantName->c_str());
+       }
+       else if (m_symbol)
+       {
+               printf("sizeof:\n");
+               m_symbol->printTree(indent + 2);
+       }
+}
+
+ExprASTNode * SizeofOperatorASTNode::reduce(EvalContext & context)
+{
+       // One or the other must be defined.
+       assert(m_constantName || m_symbol);
+       
+       EvalContext::SourceFileManager * manager = context.getSourceFileManager();
+       assert(manager);
+       
+       unsigned sizeInBytes = 0;
+       SourceFile * sourceFile;
+       
+       if (m_symbol)
+       {
+               // Get the symbol name.
+               std::string * symbolName = m_symbol->getSymbolName();
+               assert(symbolName);
+               
+               // Get the source file, using the default if one is not specified.
+               std::string * sourceName = m_symbol->getSource();
+               if (sourceName)
+               {
+                       sourceFile = manager->getSourceFile(*sourceName);
+                       if (!sourceFile)
+                       {
+                               throw semantic_error(format_string("line %d: invalid source file: %s", getFirstLine(), sourceName->c_str()));
+                       }
+               }
+               else
+               {
+                       sourceFile = manager->getDefaultSourceFile();
+                       if (!sourceFile)
+                       {
+                               throw semantic_error(format_string("line %d: no default source file is set", getFirstLine()));
+                       }
+               }
+               
+               // Get the size of the symbol.
+               if (sourceFile->hasSymbol(*symbolName))
+               {
+                       sizeInBytes = sourceFile->getSymbolSize(*symbolName);
+               }
+       }
+       else if (m_constantName)
+       {
+               // See if the "constant" is really a constant or if it's a source name.
+               if (manager->hasSourceFile(m_constantName))
+               {
+                       sourceFile = manager->getSourceFile(m_constantName);
+                       if (sourceFile)
+                       {
+                               sizeInBytes = sourceFile->getSize();
+                       }
+               }
+               else
+               {
+                       // Regular constant.
+                       if (!context.isVariableDefined(*m_constantName))
+                       {
+                               throw semantic_error(format_string("line %d: cannot get size of undefined constant %s", getFirstLine(), m_constantName->c_str()));
+                       }
+                       
+                       int_size_t intSize = context.getVariableSize(*m_constantName);
+                       switch (intSize)
+                       {
+                               case kWordSize:
+                                       sizeInBytes = sizeof(uint32_t);
+                                       break;
+                               case kHalfWordSize:
+                                       sizeInBytes = sizeof(uint16_t);
+                                       break;
+                               case kByteSize:
+                                       sizeInBytes = sizeof(uint8_t);
+                                       break;
+                       }
+               }
+       }
+       
+       // Return function result as an expression node
+       return new IntConstExprASTNode(sizeInBytes);
+}
+
+#pragma mark = BinaryOpExprASTNode =
+
+BinaryOpExprASTNode::BinaryOpExprASTNode(const BinaryOpExprASTNode & other)
+:      ExprASTNode(other), m_left(), m_op(other.m_op), m_right()
+{
+       m_left = dynamic_cast<ExprASTNode*>(other.m_left->clone());
+       m_right = dynamic_cast<ExprASTNode*>(other.m_right->clone());
+}
+
+void BinaryOpExprASTNode::printTree(int indent) const
+{
+       ExprASTNode::printTree(indent);
+
+       printIndent(indent + 1);
+       printf("left:\n");
+       if (m_left) m_left->printTree(indent + 2);
+       
+       printIndent(indent + 1);
+       printf("op: %s\n", getOperatorName().c_str());
+
+       printIndent(indent + 1);
+       printf("right:\n");
+       if (m_right) m_right->printTree(indent + 2);
+}
+
+std::string BinaryOpExprASTNode::getOperatorName() const
+{
+       switch (m_op)
+       {
+               case kAdd:
+                       return "+";
+               case kSubtract:
+                       return "-";
+               case kMultiply:
+                       return "*";
+               case kDivide:
+                       return "/";
+               case kModulus:
+                       return "%";
+               case kPower:
+                       return "**";
+               case kBitwiseAnd:
+                       return "&";
+               case kBitwiseOr:
+                       return "|";
+               case kBitwiseXor:
+                       return "^";
+               case kShiftLeft:
+                       return "<<";
+               case kShiftRight:
+                       return ">>";
+               case kLessThan:
+                       return "<";
+               case kGreaterThan:
+                       return ">";
+               case kLessThanEqual:
+                       return "<=";
+               case kGreaterThanEqual:
+                       return ">";
+               case kEqual:
+                       return "==";
+               case kNotEqual:
+                       return "!=";
+               case kBooleanAnd:
+                       return "&&";
+               case kBooleanOr:
+                       return "||";
+       }
+       
+       return "???";
+}
+
+//! \todo Fix power operator under windows!!!
+//!
+ExprASTNode * BinaryOpExprASTNode::reduce(EvalContext & context)
+{
+       if (!m_left || !m_right)
+       {
+               return this;
+       }
+       
+       IntConstExprASTNode * leftIntConst = NULL;
+       IntConstExprASTNode * rightIntConst = NULL;
+       uint32_t leftValue;
+       uint32_t rightValue;
+       uint32_t result = 0;
+       
+       // Always reduce the left hand side.
+       m_left = m_left->reduce(context);
+       leftIntConst = dynamic_cast<IntConstExprASTNode*>(m_left.get());
+       if (!leftIntConst)
+       {
+               throw semantic_error(format_string("left hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str()));
+       }
+       leftValue = leftIntConst->getValue();
+       
+       // Boolean && and || operators are handled separately so that we can perform
+       // short-circuit evaluation.
+       if (m_op == kBooleanAnd || m_op == kBooleanOr)
+       {
+               // Reduce right hand side only if required to evaluate the boolean operator.
+               if ((m_op == kBooleanAnd && leftValue != 0) || (m_op == kBooleanOr && leftValue == 0))
+               {
+                       m_right = m_right->reduce(context);
+                       rightIntConst = dynamic_cast<IntConstExprASTNode*>(m_right.get());
+                       if (!rightIntConst)
+                       {
+                               throw semantic_error(format_string("right hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str()));
+                       }
+                       rightValue = rightIntConst->getValue();
+                       
+                       // Perform the boolean operation.
+                       switch (m_op)
+                       {
+                               case kBooleanAnd:
+                                       result = leftValue && rightValue;
+                                       break;
+                               
+                               case kBooleanOr:
+                                       result = leftValue && rightValue;
+                                       break;
+                       }
+               }
+               else if (m_op == kBooleanAnd)
+               {
+                       // The left hand side is false, so the && operator's result must be false
+                       // without regard to the right hand side.
+                       result = 0;
+               }
+               else if (m_op == kBooleanOr)
+               {
+                       // The left hand value is true so the || result is automatically true.
+                       result = 1;
+               }
+       }
+       else
+       {
+               // Reduce right hand side always for most operators.
+               m_right = m_right->reduce(context);
+               rightIntConst = dynamic_cast<IntConstExprASTNode*>(m_right.get());
+               if (!rightIntConst)
+               {
+                       throw semantic_error(format_string("right hand side of %s operator failed to evaluate to an integer", getOperatorName().c_str()));
+               }
+               rightValue = rightIntConst->getValue();
+               
+               switch (m_op)
+               {
+                       case kAdd:
+                               result = leftValue + rightValue;
+                               break;
+                       case kSubtract:
+                               result = leftValue - rightValue;
+                               break;
+                       case kMultiply:
+                               result = leftValue * rightValue;
+                               break;
+                       case kDivide:
+                               result = leftValue / rightValue;
+                               break;
+                       case kModulus:
+                               result = leftValue % rightValue;
+                               break;
+                       case kPower:
+                       #ifdef WIN32
+                               result = 0;
+                       #else
+                               result = lroundf(powf(float(leftValue), float(rightValue)));
+                       #endif
+                               break;
+                       case kBitwiseAnd:
+                               result = leftValue & rightValue;
+                               break;
+                       case kBitwiseOr:
+                               result = leftValue | rightValue;
+                               break;
+                       case kBitwiseXor:
+                               result = leftValue ^ rightValue;
+                               break;
+                       case kShiftLeft:
+                               result = leftValue << rightValue;
+                               break;
+                       case kShiftRight:
+                               result = leftValue >> rightValue;
+                               break;
+                       case kLessThan:
+                               result = leftValue < rightValue;
+                               break;
+                       case kGreaterThan:
+                               result = leftValue > rightValue;
+                               break;
+                       case kLessThanEqual:
+                               result = leftValue <= rightValue;
+                               break;
+                       case kGreaterThanEqual:
+                               result = leftValue >= rightValue;
+                               break;
+                       case kEqual:
+                               result = leftValue == rightValue;
+                               break;
+                       case kNotEqual:
+                               result = leftValue != rightValue;
+                               break;
+               }
+       }
+       
+       // Create the result value.
+       int_size_t resultSize;
+       if (leftIntConst && rightIntConst)
+       {
+               resultSize = resultIntSize(leftIntConst->getSize(), rightIntConst->getSize());
+       }
+       else if (leftIntConst)
+       {
+               resultSize = leftIntConst->getSize();
+       }
+       else
+       {
+               // This shouldn't really be possible, but just in case.
+               resultSize = kWordSize;
+       }
+       return new IntConstExprASTNode(result, resultSize);
+}
+
+#pragma mark = IntSizeExprASTNode =
+
+IntSizeExprASTNode::IntSizeExprASTNode(const IntSizeExprASTNode & other)
+:      ExprASTNode(other), m_expr(), m_size(other.m_size)
+{
+       m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
+}
+
+void IntSizeExprASTNode::printTree(int indent) const
+{
+       ExprASTNode::printTree(indent);
+       
+       char sizeChar='?';
+       switch (m_size)
+       {
+               case kWordSize:
+                       sizeChar = 'w';
+                       break;
+               case kHalfWordSize:
+                       sizeChar = 'h';
+                       break;
+               case kByteSize:
+                       sizeChar = 'b';
+                       break;
+       }
+       printIndent(indent + 1);
+       printf("size: %c\n", sizeChar);
+       
+       printIndent(indent + 1);
+       printf("expr:\n");
+       if (m_expr) m_expr->printTree(indent + 2);
+}
+
+ExprASTNode * IntSizeExprASTNode::reduce(EvalContext & context)
+{
+       if (!m_expr)
+       {
+               return this;
+       }
+       
+       m_expr = m_expr->reduce(context);
+       IntConstExprASTNode * intConst = dynamic_cast<IntConstExprASTNode*>(m_expr.get());
+       if (!intConst)
+       {
+               return this;
+       }
+       
+       return new IntConstExprASTNode(intConst->getValue(), m_size);
+}
+
+#pragma mark = ExprConstASTNode =
+
+ExprConstASTNode::ExprConstASTNode(const ExprConstASTNode & other)
+:      ConstASTNode(other), m_expr()
+{
+       m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
+}
+
+void ExprConstASTNode::printTree(int indent) const
+{
+       ConstASTNode::printTree(indent);
+       if (m_expr) m_expr->printTree(indent + 1);
+}
+
+#pragma mark = StringConstASTNode =
+
+StringConstASTNode::StringConstASTNode(const StringConstASTNode & other)
+:      ConstASTNode(other), m_value()
+{
+       m_value = new std::string(other.m_value);
+}
+
+void StringConstASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       printf("%s(%s)\n", nodeName().c_str(), m_value->c_str());
+}
+
+#pragma mark = BlobConstASTNode =
+
+BlobConstASTNode::BlobConstASTNode(const BlobConstASTNode & other)
+:      ConstASTNode(other), m_blob()
+{
+       m_blob = new Blob(*other.m_blob);
+}
+
+void BlobConstASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       
+       const uint8_t * dataPtr = m_blob->getData();
+       unsigned dataLen = m_blob->getLength();
+       printf("%s(%p:%d)\n", nodeName().c_str(), dataPtr, dataLen);
+}
+
+#pragma mark = IVTConstASTNode =
+
+IVTConstASTNode::IVTConstASTNode(const IVTConstASTNode & other)
+:      ConstASTNode(other), m_fields()
+{
+       m_fields = dynamic_cast<ListASTNode*>(other.m_fields->clone());
+}
+
+void IVTConstASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       printf("%s:\n", nodeName().c_str());
+    if (m_fields)
+    {
+        m_fields->printTree(indent + 1);
+    }
+}
+
+#pragma mark = AssignmentASTNode =
+
+AssignmentASTNode::AssignmentASTNode(const AssignmentASTNode & other)
+:      ASTNode(other), m_ident(), m_value()
+{
+       m_ident = new std::string(*other.m_ident);
+       m_value = dynamic_cast<ConstASTNode*>(other.m_value->clone());
+}
+
+void AssignmentASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       printf("%s(%s)\n", nodeName().c_str(), m_ident->c_str());
+       
+       if (m_value) m_value->printTree(indent + 1);
+}
+
+#pragma mark = SourceDefASTNode =
+
+SourceDefASTNode::SourceDefASTNode(const SourceDefASTNode & other)
+:      ASTNode(other), m_name()
+{
+       m_name = new std::string(*other.m_name);
+}
+
+#pragma mark = PathSourceDefASTNode =
+
+PathSourceDefASTNode::PathSourceDefASTNode(const PathSourceDefASTNode & other)
+:      SourceDefASTNode(other), m_path()
+{
+       m_path = new std::string(*other.m_path);
+}
+
+void PathSourceDefASTNode::printTree(int indent) const
+{
+       SourceDefASTNode::printTree(indent);
+       
+       printIndent(indent+1);
+       printf("path: %s\n", m_path->c_str());
+       
+       printIndent(indent+1);
+       printf("attributes:\n");
+       if (m_attributes)
+       {
+               m_attributes->printTree(indent+2);
+       }
+}
+
+#pragma mark = ExternSourceDefASTNode =
+
+ExternSourceDefASTNode::ExternSourceDefASTNode(const ExternSourceDefASTNode & other)
+:      SourceDefASTNode(other), m_expr()
+{
+       m_expr = dynamic_cast<ExprASTNode*>(other.m_expr->clone());
+}
+
+void ExternSourceDefASTNode::printTree(int indent) const
+{
+       SourceDefASTNode::printTree(indent);
+       
+       printIndent(indent+1);
+       printf("expr:\n");
+       if (m_expr) m_expr->printTree(indent + 2);
+       
+       printIndent(indent+1);
+       printf("attributes:\n");
+       if (m_attributes)
+       {
+               m_attributes->printTree(indent+2);
+       }
+}
+
+#pragma mark = SectionContentsASTNode =
+
+SectionContentsASTNode::SectionContentsASTNode(const SectionContentsASTNode & other)
+:      ASTNode(other), m_sectionExpr()
+{
+       m_sectionExpr = dynamic_cast<ExprASTNode*>(other.m_sectionExpr->clone());
+}
+
+void SectionContentsASTNode::printTree(int indent) const
+{
+       ASTNode::printTree(indent);
+       
+       printIndent(indent + 1);
+       printf("section#:\n");
+       if (m_sectionExpr) m_sectionExpr->printTree(indent + 2);
+}
+
+#pragma mark = DataSectionContentsASTNode =
+
+DataSectionContentsASTNode::DataSectionContentsASTNode(const DataSectionContentsASTNode & other)
+:      SectionContentsASTNode(other), m_contents()
+{
+       m_contents = dynamic_cast<ASTNode*>(other.m_contents->clone());
+}
+
+void DataSectionContentsASTNode::printTree(int indent) const
+{
+       SectionContentsASTNode::printTree(indent);
+       
+       if (m_contents)
+       {
+               m_contents->printTree(indent + 1);
+       }
+}
+
+#pragma mark = BootableSectionContentsASTNode =
+
+BootableSectionContentsASTNode::BootableSectionContentsASTNode(const BootableSectionContentsASTNode & other)
+:      SectionContentsASTNode(other), m_statements()
+{
+       m_statements = dynamic_cast<ListASTNode*>(other.m_statements->clone());
+}
+
+void BootableSectionContentsASTNode::printTree(int indent) const
+{
+       SectionContentsASTNode::printTree(indent);
+       
+       printIndent(indent + 1);
+       printf("statements:\n");
+       if (m_statements) m_statements->printTree(indent + 2);
+}
+
+#pragma mark = IfStatementASTNode =
+
+//! \warning Be careful; this method could enter an infinite loop if m_nextIf feeds
+//!            back onto itself. m_nextIf must be NULL at some point down the next if list.
+IfStatementASTNode::IfStatementASTNode(const IfStatementASTNode & other)
+:      StatementASTNode(),
+       m_conditionExpr(),
+       m_ifStatements(),
+       m_nextIf(),
+       m_elseStatements()
+{
+       m_conditionExpr = dynamic_cast<ExprASTNode*>(other.m_conditionExpr->clone());
+       m_ifStatements = dynamic_cast<ListASTNode*>(other.m_ifStatements->clone());
+       m_nextIf = dynamic_cast<IfStatementASTNode*>(other.m_nextIf->clone());
+       m_elseStatements = dynamic_cast<ListASTNode*>(other.m_elseStatements->clone());
+}
+
+#pragma mark = ModeStatementASTNode =
+
+ModeStatementASTNode::ModeStatementASTNode(const ModeStatementASTNode & other)
+:      StatementASTNode(other), m_modeExpr()
+{
+       m_modeExpr = dynamic_cast<ExprASTNode*>(other.m_modeExpr->clone());
+}
+
+void ModeStatementASTNode::printTree(int indent) const
+{
+       StatementASTNode::printTree(indent);
+       printIndent(indent + 1);
+       printf("mode:\n");
+       if (m_modeExpr) m_modeExpr->printTree(indent + 2);
+}
+
+#pragma mark = MessageStatementASTNode =
+
+MessageStatementASTNode::MessageStatementASTNode(const MessageStatementASTNode & other)
+:      StatementASTNode(other), m_type(other.m_type), m_message()
+{
+       m_message = new std::string(*other.m_message);
+}
+
+void MessageStatementASTNode::printTree(int indent) const
+{
+       StatementASTNode::printTree(indent);
+       printIndent(indent + 1);
+       printf("%s: %s\n", getTypeName(), m_message->c_str());
+}
+
+const char * MessageStatementASTNode::getTypeName() const
+{
+       switch (m_type)
+       {
+               case kInfo:
+                       return "info";
+               
+               case kWarning:
+                       return "warning";
+               
+               case kError:
+                       return "error";
+       }
+       
+       return "unknown";
+}
+
+#pragma mark = LoadStatementASTNode =
+
+LoadStatementASTNode::LoadStatementASTNode(const LoadStatementASTNode & other)
+:      StatementASTNode(other), m_data(), m_target(), m_isDCDLoad(other.m_isDCDLoad)
+{
+       m_data = other.m_data->clone();
+       m_target = other.m_target->clone();
+}
+
+void LoadStatementASTNode::printTree(int indent) const
+{
+       StatementASTNode::printTree(indent);
+       
+       printIndent(indent + 1);
+       printf("data:\n");
+       if (m_data) m_data->printTree(indent + 2);
+       
+       printIndent(indent + 1);
+       printf("target:\n");
+       if (m_target) m_target->printTree(indent + 2);
+}
+
+#pragma mark = CallStatementASTNode =
+
+CallStatementASTNode::CallStatementASTNode(const CallStatementASTNode & other)
+:      StatementASTNode(other), m_type(other.m_type), m_target(), m_arg()
+{
+       m_target = other.m_target->clone();
+       m_arg = other.m_arg->clone();
+}
+
+void CallStatementASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       printf("%s(%s)%s\n", nodeName().c_str(), (m_type == kCallType ? "call" : "jump"), (m_isHAB ? "/HAB" : ""));
+       
+       printIndent(indent + 1);
+       printf("target:\n");
+       if (m_target) m_target->printTree(indent + 2);
+       
+       printIndent(indent + 1);
+       printf("arg:\n");
+       if (m_arg) m_arg->printTree(indent + 2);
+}
+
+#pragma mark = SourceASTNode =
+
+SourceASTNode::SourceASTNode(const SourceASTNode & other)
+:      ASTNode(other), m_name()
+{
+       m_name = new std::string(*other.m_name);
+}
+
+void SourceASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       printf("%s(%s)\n", nodeName().c_str(), m_name->c_str());
+}
+
+#pragma mark = SectionMatchListASTNode =
+
+SectionMatchListASTNode::SectionMatchListASTNode(const SectionMatchListASTNode & other)
+:      ASTNode(other), m_sections(), m_source()
+{
+       if (other.m_sections)
+       {
+               m_sections = dynamic_cast<ListASTNode *>(other.m_sections->clone());
+       }
+       
+       if (other.m_source)
+       {
+               m_source = new std::string(*other.m_source);
+       }
+}
+
+void SectionMatchListASTNode::printTree(int indent) const
+{
+       ASTNode::printTree(indent);
+       
+       printIndent(indent+1);
+       printf("sections:\n");
+       if (m_sections)
+       {
+               m_sections->printTree(indent+2);
+       }
+       
+       printIndent(indent+1);
+       printf("source: ", m_source->c_str());
+       if (m_source)
+       {
+               printf("%s\n", m_source->c_str());
+       }
+       else
+       {
+               printf("\n");
+       }
+}
+
+#pragma mark = SectionASTNode =
+
+SectionASTNode::SectionASTNode(const SectionASTNode & other)
+:      ASTNode(other), m_name(), m_source()
+{
+       m_action = other.m_action;
+       
+       if (other.m_name)
+       {
+               m_name = new std::string(*other.m_name);
+       }
+       
+       if (other.m_source)
+       {
+               m_source = new std::string(*other.m_source);
+       }
+}
+
+void SectionASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       
+       const char * actionName;
+       switch (m_action)
+       {
+               case kInclude:
+                       actionName = "include";
+                       break;
+               case kExclude:
+                       actionName = "exclude";
+                       break;
+       }
+       
+       if (m_source)
+       {
+               printf("%s(%s:%s:%s)\n", nodeName().c_str(), actionName, m_name->c_str(), m_source->c_str());
+       }
+       else
+       {
+               printf("%s(%s:%s)\n", nodeName().c_str(), actionName, m_name->c_str());
+       }
+}
+
+#pragma mark = SymbolASTNode =
+
+SymbolASTNode::SymbolASTNode(const SymbolASTNode & other)
+:      ASTNode(other), m_symbol(), m_source()
+{
+       m_symbol = new std::string(*other.m_symbol);
+       m_source = new std::string(*other.m_source);
+}
+
+void SymbolASTNode::printTree(int indent) const
+{
+       printIndent(indent);
+       
+       const char * symbol = NULL;
+       if (m_symbol)
+       {
+               symbol = m_symbol->c_str();
+       }
+       
+       const char * source = NULL;
+       if (m_source)
+       {
+               source = m_source->c_str();
+       }
+       
+       printf("%s(", nodeName().c_str());
+       if (source)
+       {
+               printf(source);
+       }
+       else
+       {
+               printf(".");
+       }
+       printf(":");
+       if (symbol)
+       {
+               printf(symbol);
+       }
+       else
+       {
+               printf(".");
+       }
+       printf(")\n");
+}
+
+#pragma mark = AddressRangeASTNode =
+
+AddressRangeASTNode::AddressRangeASTNode(const AddressRangeASTNode & other)
+:      ASTNode(other), m_begin(), m_end()
+{
+       m_begin = other.m_begin->clone();
+       m_end = other.m_end->clone();
+}
+
+void AddressRangeASTNode::printTree(int indent) const
+{
+       ASTNode::printTree(indent);
+       
+       printIndent(indent + 1);
+       printf("begin:\n");
+       if (m_begin) m_begin->printTree(indent + 2);
+       
+       printIndent(indent + 1);
+       printf("end:\n");
+       if (m_end) m_end->printTree(indent + 2);
+}
+
+#pragma mark = FromStatementASTNode =
+
+FromStatementASTNode::FromStatementASTNode(std::string * source, ListASTNode * statements)
+:      StatementASTNode(), m_source(source), m_statements(statements)
+{
+}
+
+FromStatementASTNode::FromStatementASTNode(const FromStatementASTNode & other)
+:      StatementASTNode(), m_source(), m_statements()
+{
+       m_source = new std::string(*other.m_source);
+       m_statements = dynamic_cast<ListASTNode*>(other.m_statements->clone());
+}
+
+void FromStatementASTNode::printTree(int indent) const
+{
+       ASTNode::printTree(indent);
+       
+       printIndent(indent + 1);
+       printf("source: ");
+       if (m_source) printf("%s\n", m_source->c_str());
+       
+       printIndent(indent + 1);
+       printf("statements:\n");
+       if (m_statements) m_statements->printTree(indent + 2);
+}
+
diff --git a/tools/elftosb/elftosb2/ElftosbAST.h b/tools/elftosb/elftosb2/ElftosbAST.h
new file mode 100644 (file)
index 0000000..cb70f49
--- /dev/null
@@ -0,0 +1,1227 @@
+/*
+ * File:       ElftosbAST.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_ElftosbAST_h_)
+#define _ElftosbAST_h_
+
+#include "stdafx.h"
+#include <string>
+#include <list>
+#include "smart_ptr.h"
+#include "EvalContext.h"
+
+namespace elftosb
+{
+
+// forward reference
+class SymbolASTNode;
+
+/*!
+ * \brief Token location in the source file.
+ */
+struct token_loc_t
+{
+       int m_firstLine;        //!< Starting line of the token.
+       int m_lastLine;         //!< Ending line of the token.
+};
+
+/*!
+ * \brief The base class for all AST node classes.
+ */
+class ASTNode
+{
+public:
+       //! \brief Default constructor.
+       ASTNode() : m_parent(0) {}
+       
+       //! \brief Constructor taking a parent node.
+       ASTNode(ASTNode * parent) : m_parent(parent) {}
+       
+       //! \brief Copy constructor.
+       ASTNode(const ASTNode & other) : m_parent(other.m_parent) {}
+       
+       //! \brief Destructor.
+       virtual ~ASTNode() {}
+       
+       //! \brief Returns an exact duplicate of this object.
+       virtual ASTNode * clone() const = 0;
+       
+       //! \brief Returns the name of the object's class.
+       virtual std::string nodeName() const { return "ASTNode"; }
+
+       //! \name Parents
+       //@{
+       virtual ASTNode * getParent() const { return m_parent; }
+       virtual void setParent(ASTNode * newParent) { m_parent = newParent; }
+       //@}
+       
+       //! \name Tree printing
+       //@{
+       virtual void printTree() const { printTree(0); }
+       virtual void printTree(int indent) const;
+       //@}
+       
+       //! \name Location
+       //@{
+       virtual void setLocation(token_loc_t & loc) { m_location = loc; }
+       virtual void setLocation(token_loc_t & first, token_loc_t & last);
+       virtual void setLocation(ASTNode * loc) { setLocation(loc->getLocation()); }
+       virtual void setLocation(ASTNode * first, ASTNode * last);
+       
+       virtual token_loc_t & getLocation() { return m_location; }
+       virtual const token_loc_t & getLocation() const { return m_location; }
+       
+       virtual int getFirstLine() { return m_location.m_firstLine; }
+       virtual int getLastLine() { return m_location.m_lastLine; }
+       //@}
+
+protected:
+       ASTNode * m_parent;     //!< Pointer to parent node of this object. May be NULL.
+       token_loc_t m_location; //!< Location of this node in the source file.
+       
+       //! \brief Prints \a indent number of spaces.
+       void printIndent(int indent) const;
+};
+
+/*!
+ * \brief AST node that contains other AST nodes.
+ *
+ * Unlike other AST nodes, the location of a ListASTNode is computed dynamically
+ * based on the nodes in its list. Or mostly dynamic at least. The updateLocation()
+ * method is used to force the list object to recalculate its beginning and ending
+ * line numbers.
+ *
+ * \todo Figure out why it crashes in the destructor when the
+ *       ast_list_t type is a list of smart_ptr<ASTNode>.
+ */
+class ListASTNode : public ASTNode
+{
+public:
+       typedef std::list< /*smart_ptr<ASTNode>*/ ASTNode * > ast_list_t;       
+       typedef ast_list_t::iterator iterator;
+       typedef ast_list_t::const_iterator const_iterator;
+
+public:
+       ListASTNode() {}
+       
+       ListASTNode(const ListASTNode & other);
+       
+       virtual ~ListASTNode();
+       
+       virtual ASTNode * clone() const { return new ListASTNode(*this); }
+       
+       virtual std::string nodeName() const { return "ListASTNode"; }
+
+       virtual void printTree(int indent) const;
+
+       //! \name List operations
+       //@{
+       //! \brief Adds \a node to the end of the ordered list of child nodes.
+       virtual void appendNode(ASTNode * node);
+       
+       //! \brief Returns the number of nodes in this list.
+       virtual unsigned nodeCount() const { return static_cast<unsigned>(m_list.size()); }
+       //@}
+
+       //! \name Node iterators
+       //@{
+       inline iterator begin() { return m_list.begin(); }
+       inline iterator end() { return m_list.end(); }
+
+       inline const_iterator begin() const { return m_list.begin(); }
+       inline const_iterator end() const { return m_list.end(); }
+       //@}
+       
+       //! \name Location
+       //@{
+       virtual void updateLocation();
+       //@}
+
+protected:
+       ast_list_t m_list;      //!< Ordered list of child nodes.
+};
+
+/*!
+ *
+ */
+class OptionsBlockASTNode : public ASTNode
+{
+public:
+       OptionsBlockASTNode(ListASTNode * options) : ASTNode(), m_options(options) {}
+       
+       inline ListASTNode * getOptions() { return m_options; }
+       
+       virtual ASTNode * clone() const { return NULL; }
+
+protected:
+       smart_ptr<ListASTNode> m_options;
+};
+
+/*!
+ *
+ */
+class ConstantsBlockASTNode : public ASTNode
+{
+public:
+       ConstantsBlockASTNode(ListASTNode * constants) : ASTNode(), m_constants(constants) {}
+       
+       inline ListASTNode * getConstants() { return m_constants; }
+       
+       virtual ASTNode * clone() const { return NULL; }
+       
+protected:
+       smart_ptr<ListASTNode> m_constants;
+};
+
+/*!
+ *
+ */
+class SourcesBlockASTNode : public ASTNode
+{
+public:
+       SourcesBlockASTNode(ListASTNode * sources) : ASTNode(), m_sources(sources) {}
+       
+       inline ListASTNode * getSources() { return m_sources; }
+       
+       virtual ASTNode * clone() const { return NULL; }
+       
+protected:
+       smart_ptr<ListASTNode> m_sources;
+};
+
+/*!
+ * \brief Root node for the entire file.
+ */
+class CommandFileASTNode : public ASTNode
+{
+public:
+       CommandFileASTNode();
+       CommandFileASTNode(const CommandFileASTNode & other);
+       
+       virtual std::string nodeName() const { return "CommandFileASTNode"; }
+       
+       virtual ASTNode * clone() const { return new CommandFileASTNode(*this); }
+
+       virtual void printTree(int indent) const;
+
+       inline void setBlocks(ListASTNode * blocks) { m_blocks = blocks; }
+       inline void setOptions(ListASTNode * options) { m_options = options; }
+       inline void setConstants(ListASTNode * constants) { m_constants = constants; }
+       inline void setSources(ListASTNode * sources) { m_sources = sources; }
+       inline void setSections(ListASTNode * sections) { m_sections = sections; }
+       
+       inline ListASTNode * getBlocks() { return m_blocks; }
+       inline ListASTNode * getOptions() { return m_options; }
+       inline ListASTNode * getConstants() { return m_constants; }
+       inline ListASTNode * getSources() { return m_sources; }
+       inline ListASTNode * getSections() { return m_sections; }
+
+protected:
+       smart_ptr<ListASTNode> m_blocks;
+       smart_ptr<ListASTNode> m_options;
+       smart_ptr<ListASTNode> m_constants;
+       smart_ptr<ListASTNode> m_sources;
+       smart_ptr<ListASTNode> m_sections;
+};
+
+/*!
+ * \brief Abstract base class for all expression AST nodes.
+ */
+class ExprASTNode : public ASTNode
+{
+public:
+       ExprASTNode() : ASTNode() {}
+       ExprASTNode(const ExprASTNode & other) : ASTNode(other) {}
+
+       virtual std::string nodeName() const { return "ExprASTNode"; }
+
+       //! \brief Evaluate the expression and produce a result node to replace this one.
+       //!
+       //! The default implementation simply return this node unmodified. This
+       //! method is responsible for deleting any nodes that are no longer needed.
+       //! (?) how to delete this?
+       virtual ExprASTNode * reduce(EvalContext & context) { return this; }
+       
+       int_size_t resultIntSize(int_size_t a, int_size_t b);
+};
+
+/*!
+ *
+ */
+class IntConstExprASTNode : public ExprASTNode
+{
+public:
+       IntConstExprASTNode(uint32_t value, int_size_t size=kWordSize)
+       :       ExprASTNode(), m_value(value), m_size(size)
+       {
+       }
+       
+       IntConstExprASTNode(const IntConstExprASTNode & other);
+
+       virtual std::string nodeName() const { return "IntConstExprASTNode"; }
+       
+       virtual ASTNode * clone() const { return new IntConstExprASTNode(*this); }
+
+       virtual void printTree(int indent) const;
+       
+       uint32_t getValue() const { return m_value; }
+       int_size_t getSize() const { return m_size; }
+
+protected:
+       uint32_t m_value;
+       int_size_t m_size;
+};
+
+/*!
+ *
+ */
+class VariableExprASTNode : public ExprASTNode
+{
+public:
+       VariableExprASTNode(std::string * name) : ExprASTNode(), m_variable(name) {}
+       VariableExprASTNode(const VariableExprASTNode & other);
+       
+       inline std::string * getVariableName() { return m_variable; }
+       
+       virtual ASTNode * clone() const { return new VariableExprASTNode(*this); }
+       
+       virtual std::string nodeName() const { return "VariableExprASTNode"; }
+
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+protected:
+       smart_ptr<std::string> m_variable;
+};
+
+/*!
+ * \brief Expression node for a symbol reference.
+ *
+ * The symbol evaluates to its address.
+ */
+class SymbolRefExprASTNode : public ExprASTNode
+{
+public:
+       SymbolRefExprASTNode(SymbolASTNode * sym) : ExprASTNode(), m_symbol(sym) {}
+       SymbolRefExprASTNode(const SymbolRefExprASTNode & other);
+       
+       virtual ASTNode * clone() const { return new SymbolRefExprASTNode(*this); }
+       
+       virtual std::string nodeName() const { return "SymbolRefExprASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+protected:
+       SymbolASTNode * m_symbol;
+};
+
+/*!
+ * \brief Negates an expression.
+ */
+class NegativeExprASTNode : public ExprASTNode
+{
+public:
+       NegativeExprASTNode(ExprASTNode * expr) : ExprASTNode(), m_expr(expr) {}
+       NegativeExprASTNode(const NegativeExprASTNode & other);
+
+       virtual ASTNode * clone() const { return new NegativeExprASTNode(*this); }
+
+       virtual std::string nodeName() const { return "NegativeExprASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+       ExprASTNode * getExpr() { return m_expr; }
+
+protected:
+       smart_ptr<ExprASTNode> m_expr;
+};
+
+/*!
+ * \brief Performa a boolean inversion.
+ */
+class BooleanNotExprASTNode : public ExprASTNode
+{
+public:
+       BooleanNotExprASTNode(ExprASTNode * expr) : ExprASTNode(), m_expr(expr) {}
+       BooleanNotExprASTNode(const BooleanNotExprASTNode & other);
+
+       virtual ASTNode * clone() const { return new BooleanNotExprASTNode(*this); }
+
+       virtual std::string nodeName() const { return "BooleanNotExprASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+       ExprASTNode * getExpr() { return m_expr; }
+
+protected:
+       smart_ptr<ExprASTNode> m_expr;
+};
+
+/*!
+ * \brief Calls a built-in function with a source as the parameter.
+ */
+class SourceFileFunctionASTNode : public ExprASTNode
+{
+public:
+       SourceFileFunctionASTNode(std::string * functionName, std::string * sourceFileName) : ExprASTNode(), m_functionName(functionName), m_sourceFile(sourceFileName) {}
+       SourceFileFunctionASTNode(const SourceFileFunctionASTNode & other);
+
+       virtual ASTNode * clone() const { return new SourceFileFunctionASTNode(*this); }
+
+       virtual std::string nodeName() const { return "SourceFileFunctionASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+       std::string * getFunctionName() { return m_functionName; }
+       std::string * getSourceFile() { return m_sourceFile; }
+
+protected:
+       smart_ptr<std::string> m_functionName;
+       smart_ptr<std::string> m_sourceFile;
+};
+
+/*!
+ * \brief Returns true or false depending on whether a constant is defined.
+ */
+class DefinedOperatorASTNode : public ExprASTNode
+{
+public:
+       DefinedOperatorASTNode(std::string * constantName) : ExprASTNode(), m_constantName(constantName) {}
+       DefinedOperatorASTNode(const DefinedOperatorASTNode & other);
+
+       virtual ASTNode * clone() const { return new DefinedOperatorASTNode(*this); }
+
+       virtual std::string nodeName() const { return "DefinedOperatorASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+       std::string * getConstantName() { return m_constantName; }
+
+protected:
+       smart_ptr<std::string> m_constantName;  //!< Name of the constant.
+};
+
+class SymbolASTNode;
+
+/*!
+ * \brief Returns an integer that is the size in bytes of the operand.
+ */
+class SizeofOperatorASTNode : public ExprASTNode
+{
+public:
+       SizeofOperatorASTNode(std::string * constantName) : ExprASTNode(), m_constantName(constantName), m_symbol() {}
+       SizeofOperatorASTNode(SymbolASTNode * symbol) : ExprASTNode(), m_constantName(), m_symbol(symbol) {}
+       SizeofOperatorASTNode(const SizeofOperatorASTNode & other);
+
+       virtual ASTNode * clone() const { return new SizeofOperatorASTNode(*this); }
+
+       virtual std::string nodeName() const { return "SizeofOperatorASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+       std::string * getConstantName() { return m_constantName; }
+       SymbolASTNode * getSymbol() { return m_symbol; }
+
+protected:
+       smart_ptr<std::string> m_constantName;  //!< Name of the constant.
+       smart_ptr<SymbolASTNode> m_symbol;      //!< Symbol reference. If this is non-NULL then the constant name is used instead.
+};
+
+/*!
+ *
+ */
+class BinaryOpExprASTNode : public ExprASTNode
+{
+public:
+       enum operator_t
+       {
+               kAdd,
+               kSubtract,
+               kMultiply,
+               kDivide,
+               kModulus,
+               kPower,
+               kBitwiseAnd,
+               kBitwiseOr,
+               kBitwiseXor,
+               kShiftLeft,
+               kShiftRight,
+               kLessThan,
+               kGreaterThan,
+               kLessThanEqual,
+               kGreaterThanEqual,
+               kEqual,
+               kNotEqual,
+               kBooleanAnd,
+               kBooleanOr
+       };
+       
+       BinaryOpExprASTNode(ExprASTNode * left, operator_t op, ExprASTNode * right)
+       :       ExprASTNode(), m_left(left), m_op(op), m_right(right)
+       {
+       }
+       
+       BinaryOpExprASTNode(const BinaryOpExprASTNode & other);
+       
+       virtual ASTNode * clone() const { return new BinaryOpExprASTNode(*this); }
+
+       virtual std::string nodeName() const { return "BinaryOpExprASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+       ExprASTNode * getLeftExpr() { return m_left; }
+       ExprASTNode * getRightExpr() { return m_right; }
+       operator_t getOp() const { return m_op; }
+
+protected:
+       smart_ptr<ExprASTNode> m_left;
+       smart_ptr<ExprASTNode> m_right;
+       operator_t m_op;
+       
+       std::string getOperatorName() const;
+};
+
+/*!
+ * \brief Negates an expression.
+ */
+class IntSizeExprASTNode : public ExprASTNode
+{
+public:
+       IntSizeExprASTNode(ExprASTNode * expr, int_size_t intSize) : ExprASTNode(), m_expr(expr), m_size(intSize) {}
+       IntSizeExprASTNode(const IntSizeExprASTNode & other);
+       
+       virtual ASTNode * clone() const { return new IntSizeExprASTNode(*this); }
+
+       virtual std::string nodeName() const { return "IntSizeExprASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       virtual ExprASTNode * reduce(EvalContext & context);
+       
+       ExprASTNode * getExpr() { return m_expr; }
+       int_size_t getIntSize() { return m_size; }
+
+protected:
+       smart_ptr<ExprASTNode> m_expr;
+       int_size_t m_size;
+};
+
+/*!
+ * Base class for const AST nodes.
+ */
+class ConstASTNode : public ASTNode
+{
+public:
+       ConstASTNode() : ASTNode() {}
+       ConstASTNode(const ConstASTNode & other) : ASTNode(other) {}
+
+protected:
+};
+
+/*!
+ *
+ */
+class ExprConstASTNode : public ConstASTNode
+{
+public:
+       ExprConstASTNode(ExprASTNode * expr) : ConstASTNode(), m_expr(expr) {}
+       ExprConstASTNode(const ExprConstASTNode & other);
+       
+       virtual ASTNode * clone() const { return new ExprConstASTNode(*this); }
+
+       virtual std::string nodeName() const { return "ExprConstASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       ExprASTNode * getExpr() { return m_expr; }
+
+protected:
+       smart_ptr<ExprASTNode> m_expr;
+};
+
+/*!
+ *
+ */
+class StringConstASTNode : public ConstASTNode
+{
+public:
+       StringConstASTNode(std::string * value) : ConstASTNode(), m_value(value) {}
+       StringConstASTNode(const StringConstASTNode & other);
+       
+       virtual ASTNode * clone() const { return new StringConstASTNode(*this); }
+
+       virtual std::string nodeName() const { return "StringConstASTNode"; }
+       
+       virtual void printTree(int indent) const;
+
+       std::string * getString() { return m_value; }
+
+protected:
+       smart_ptr<std::string> m_value;
+};
+
+/*!
+ *
+ */
+class BlobConstASTNode : public ConstASTNode
+{
+public:
+       BlobConstASTNode(Blob * value) : ConstASTNode(), m_blob(value) {}
+       BlobConstASTNode(const BlobConstASTNode & other);
+       
+       virtual ASTNode * clone() const { return new BlobConstASTNode(*this); }
+
+       virtual std::string nodeName() const { return "BlobConstASTNode"; }
+       
+       virtual void printTree(int indent) const;
+
+       Blob * getBlob() { return m_blob; }
+
+protected:
+       smart_ptr<Blob> m_blob;
+};
+
+// Forward declaration.
+struct hab_ivt;
+
+/*!
+ * \brief Node for a constant IVT structure as used by HAB4.
+ */
+class IVTConstASTNode : public ConstASTNode
+{
+public:
+    IVTConstASTNode() : ConstASTNode(), m_fields() {}
+    IVTConstASTNode(const IVTConstASTNode & other);
+    
+       virtual ASTNode * clone() const { return new IVTConstASTNode(*this); }
+    
+       virtual std::string nodeName() const { return "IVTConstASTNode"; }
+
+       virtual void printTree(int indent) const;
+    
+    void setFieldAssignments(ListASTNode * fields) { m_fields = fields; }
+    ListASTNode * getFieldAssignments() { return m_fields; }
+
+protected:
+    //! Fields of the IVT are set through assignment statements.
+    smart_ptr<ListASTNode> m_fields;
+};
+
+/*!
+ *
+ */
+class AssignmentASTNode : public ASTNode
+{
+public:
+       AssignmentASTNode(std::string * ident, ASTNode * value)
+       :       ASTNode(), m_ident(ident), m_value(value)
+       {
+       }
+       
+       AssignmentASTNode(const AssignmentASTNode & other);
+       
+       virtual ASTNode * clone() const { return new AssignmentASTNode(*this); }
+
+       virtual std::string nodeName() const { return "AssignmentASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline std::string * getIdent() { return m_ident; }
+       inline ASTNode * getValue() { return m_value; }
+
+protected:
+       smart_ptr<std::string> m_ident;
+       smart_ptr<ASTNode> m_value;
+};
+
+/*!
+ * Base class for PathSourceDefASTNode and ExternSourceDefASTNode.
+ */
+class SourceDefASTNode : public ASTNode
+{
+public:
+       SourceDefASTNode(std::string * name) : m_name(name) {}
+       SourceDefASTNode(const SourceDefASTNode & other);
+       
+       inline std::string * getName() { return m_name; }
+
+       inline void setAttributes(ListASTNode * attributes) { m_attributes = attributes; }
+       inline ListASTNode * getAttributes() { return m_attributes; }
+       
+protected:
+       smart_ptr<std::string> m_name;
+       smart_ptr<ListASTNode> m_attributes;
+};
+
+/*!
+ *
+ */
+class PathSourceDefASTNode : public SourceDefASTNode
+{
+public:
+       PathSourceDefASTNode(std::string * name, std::string * path)
+       :       SourceDefASTNode(name), m_path(path)
+       {
+       }
+       
+       PathSourceDefASTNode(const PathSourceDefASTNode & other);
+       
+       virtual PathSourceDefASTNode * clone() const { return new PathSourceDefASTNode(*this); }
+
+       virtual std::string nodeName() const { return "PathSourceDefASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       std::string * getPath() { return m_path; }
+       
+protected:
+       smart_ptr<std::string> m_path;
+};
+
+/*!
+ *
+ */
+class ExternSourceDefASTNode : public SourceDefASTNode
+{
+public:
+       ExternSourceDefASTNode(std::string * name, ExprASTNode * expr)
+       :       SourceDefASTNode(name), m_expr(expr)
+       {
+       }
+       
+       ExternSourceDefASTNode(const ExternSourceDefASTNode & other);
+       
+       virtual ASTNode * clone() const { return new ExternSourceDefASTNode(*this); }
+
+       virtual std::string nodeName() const { return "ExternSourceDefASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       ExprASTNode * getSourceNumberExpr() { return m_expr; }
+
+protected:
+       smart_ptr<ExprASTNode> m_expr;
+};
+
+/*!
+ *
+ */
+class SectionContentsASTNode : public ASTNode
+{
+public:
+       SectionContentsASTNode() : m_sectionExpr() {}
+       SectionContentsASTNode(ExprASTNode * section) : m_sectionExpr(section) {}
+       SectionContentsASTNode(const SectionContentsASTNode & other);
+       
+       virtual ASTNode * clone() const { return new SectionContentsASTNode(*this); }
+
+       virtual std::string nodeName() const { return "SectionContentsASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline void setSectionNumberExpr(ExprASTNode * section)
+       {
+               m_sectionExpr = section;
+       }
+       
+       inline ExprASTNode * getSectionNumberExpr()
+       {
+               return m_sectionExpr;
+       }
+       
+       inline void setOptions(ListASTNode * options)
+       {
+               m_options = options;
+       }
+       
+       inline ListASTNode * getOptions()
+       {
+               return m_options;
+       }
+
+protected:
+       smart_ptr<ExprASTNode> m_sectionExpr;
+       smart_ptr<ListASTNode> m_options;
+};
+
+/*!
+ * @brief Node representing a raw binary section definition.
+ */
+class DataSectionContentsASTNode : public SectionContentsASTNode
+{
+public:
+       DataSectionContentsASTNode(ASTNode * contents)
+       :       SectionContentsASTNode(), m_contents(contents)
+       {
+       }
+       
+       DataSectionContentsASTNode(const DataSectionContentsASTNode & other);
+       
+       virtual ASTNode * clone() const { return new DataSectionContentsASTNode(*this); }
+
+       virtual std::string nodeName() const { return "DataSectionContentsASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       ASTNode * getContents() { return m_contents; }
+       
+protected:
+       smart_ptr<ASTNode> m_contents;
+};
+
+/*!
+ *
+ */
+class BootableSectionContentsASTNode : public SectionContentsASTNode
+{
+public:
+       BootableSectionContentsASTNode(ListASTNode * statements)
+       :       SectionContentsASTNode(), m_statements(statements)
+       {
+       }
+       
+       BootableSectionContentsASTNode(const BootableSectionContentsASTNode & other);
+       
+       virtual ASTNode * clone() const { return new BootableSectionContentsASTNode(*this); }
+
+       virtual std::string nodeName() const { return "BootableSectionContentsASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       ListASTNode * getStatements() { return m_statements; }
+
+protected:
+       smart_ptr<ListASTNode> m_statements;
+};
+
+/*!
+ *
+ */
+class StatementASTNode : public ASTNode
+{
+public:
+       StatementASTNode() : ASTNode() {}
+       StatementASTNode(const StatementASTNode & other) : ASTNode(other) {}
+
+protected:
+};
+
+/*!
+ *
+ */
+class IfStatementASTNode : public StatementASTNode
+{
+public:
+       IfStatementASTNode() : StatementASTNode(), m_ifStatements(), m_nextIf(), m_elseStatements() {}
+       IfStatementASTNode(const IfStatementASTNode & other);
+       
+       virtual ASTNode * clone() const { return new IfStatementASTNode(*this); }
+       
+       void setConditionExpr(ExprASTNode * expr) { m_conditionExpr = expr; }
+       ExprASTNode * getConditionExpr() { return m_conditionExpr; }
+       
+       void setIfStatements(ListASTNode * statements) { m_ifStatements = statements; }
+       ListASTNode * getIfStatements() { return m_ifStatements; }
+       
+       void setNextIf(IfStatementASTNode * nextIf) { m_nextIf = nextIf; }
+       IfStatementASTNode * getNextIf() { return m_nextIf; }
+       
+       void setElseStatements(ListASTNode * statements) { m_elseStatements = statements; }
+       ListASTNode * getElseStatements() { return m_elseStatements; }
+
+protected:
+       smart_ptr<ExprASTNode> m_conditionExpr; //!< Boolean expression.
+       smart_ptr<ListASTNode> m_ifStatements;  //!< List of "if" section statements.
+       smart_ptr<IfStatementASTNode> m_nextIf; //!< Link to next "else if". If this is non-NULL then #m_elseStatements must be NULL and vice-versa.
+       smart_ptr<ListASTNode> m_elseStatements;        //!< Statements for the "else" part of the statements.
+};
+
+/*!
+ * \brief Statement to insert a ROM_MODE_CMD command.
+ */
+class ModeStatementASTNode : public StatementASTNode
+{
+public:
+       ModeStatementASTNode() : StatementASTNode(), m_modeExpr() {}
+       ModeStatementASTNode(ExprASTNode * modeExpr) : StatementASTNode(), m_modeExpr(modeExpr) {}
+       ModeStatementASTNode(const ModeStatementASTNode & other);
+       
+       virtual ASTNode * clone() const { return new ModeStatementASTNode(*this); }
+       
+       virtual std::string nodeName() const { return "ModeStatementASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline void setModeExpr(ExprASTNode * modeExpr) { m_modeExpr = modeExpr; }
+       inline ExprASTNode * getModeExpr() { return m_modeExpr; }
+
+protected:
+       smart_ptr<ExprASTNode> m_modeExpr;      //!< Expression that evaluates to the new boot mode.
+};
+
+/*!
+ * \brief Statement to print a message to the elftosb user.
+ */
+class MessageStatementASTNode : public StatementASTNode
+{
+public:
+       enum _message_type
+       {
+               kInfo,  //!< Prints an informational messag to the user.
+               kWarning,       //!< Prints a warning to the user.
+               kError  //!< Throws an error exception.
+       };
+       
+       typedef enum _message_type message_type_t;
+       
+public:
+       MessageStatementASTNode(message_type_t messageType, std::string * message) : StatementASTNode(), m_type(messageType), m_message(message) {}
+       MessageStatementASTNode(const MessageStatementASTNode & other);
+       
+       virtual ASTNode * clone() const { return new MessageStatementASTNode(*this); }
+       
+       virtual std::string nodeName() const { return "MessageStatementASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline message_type_t getType() { return m_type; }
+       inline std::string * getMessage() { return m_message; }
+       
+       const char * getTypeName() const;
+
+protected:
+       message_type_t m_type;
+       smart_ptr<std::string> m_message;       //!< Message to report.
+};
+
+/*!
+ * \brief AST node for a load statement.
+ */
+class LoadStatementASTNode : public StatementASTNode
+{
+public:
+       LoadStatementASTNode()
+       :       StatementASTNode(), m_data(), m_target(), m_isDCDLoad(false)
+       {
+       }
+       
+       LoadStatementASTNode(ASTNode * data, ASTNode * target)
+       :       StatementASTNode(), m_data(data), m_target(), m_isDCDLoad(false)
+       {
+       }
+       
+       LoadStatementASTNode(const LoadStatementASTNode & other);
+       
+       virtual ASTNode * clone() const { return new LoadStatementASTNode(*this); }
+
+       virtual std::string nodeName() const { return "LoadStatementASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline void setData(ASTNode * data) { m_data = data; }
+       inline ASTNode * getData() { return m_data; }
+       
+       inline void setTarget(ASTNode * target) { m_target = target; }
+       inline ASTNode * getTarget() { return m_target; }
+       
+       inline void setDCDLoad(bool isDCD) { m_isDCDLoad = isDCD; }
+       inline bool isDCDLoad() const { return m_isDCDLoad; }
+       
+protected:
+       smart_ptr<ASTNode> m_data;
+       smart_ptr<ASTNode> m_target;
+       bool m_isDCDLoad;
+};
+
+/*!
+ * \brief AST node for a call statement.
+ */
+class CallStatementASTNode : public StatementASTNode
+{
+public:
+       //! Possible sub-types of call statements.
+       typedef enum {
+               kCallType,
+               kJumpType
+       } call_type_t;
+       
+public:
+       CallStatementASTNode(call_type_t callType=kCallType)
+       :       StatementASTNode(), m_type(callType), m_target(), m_arg(), m_isHAB(false)
+       {
+       }
+       
+       CallStatementASTNode(call_type_t callType, ASTNode * target, ASTNode * arg)
+       :       StatementASTNode(), m_type(callType), m_target(target), m_arg(arg), m_isHAB(false)
+       {
+       }
+       
+       CallStatementASTNode(const CallStatementASTNode & other);
+       
+       virtual ASTNode * clone() const { return new CallStatementASTNode(*this); }
+
+       virtual std::string nodeName() const { return "CallStatementASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline void setCallType(call_type_t callType) { m_type = callType; }
+       inline call_type_t getCallType() { return m_type; }
+       
+       inline void setTarget(ASTNode * target) { m_target = target; }
+       inline ASTNode * getTarget() { return m_target; }
+       
+       inline void setArgument(ASTNode * arg) { m_arg = arg; }
+       inline ASTNode * getArgument() { return m_arg; }
+       
+       inline void setIsHAB(bool isHAB) { m_isHAB = isHAB; }
+       inline bool isHAB() const { return m_isHAB; }
+       
+protected:
+       call_type_t m_type;
+       smart_ptr<ASTNode> m_target;    //!< This becomes the IVT address in HAB mode.
+       smart_ptr<ASTNode> m_arg;
+       bool m_isHAB;
+};
+
+/*!
+ *
+ */
+class SourceASTNode : public ASTNode
+{
+public:
+       SourceASTNode(std::string * name) : ASTNode(), m_name(name) {}
+       SourceASTNode(const SourceASTNode & other);
+       
+       virtual ASTNode * clone() const { return new SourceASTNode(*this); }
+
+       virtual std::string nodeName() const { return "SourceASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline std::string * getSourceName() { return m_name; }
+       
+protected:
+       smart_ptr<std::string> m_name;
+};
+
+/*!
+ * \brief List of section matches for a particular source name.
+ */
+class SectionMatchListASTNode : public ASTNode
+{
+public:
+       SectionMatchListASTNode(ListASTNode * sections)
+       :       ASTNode(), m_sections(sections), m_source()
+       {
+       }
+       
+       SectionMatchListASTNode(ListASTNode * sections, std::string * source)
+       :       ASTNode(), m_sections(sections), m_source(source)
+       {
+       }
+       
+       SectionMatchListASTNode(const SectionMatchListASTNode & other);
+       
+       virtual ASTNode * clone() const { return new SectionMatchListASTNode(*this); }
+
+       virtual std::string nodeName() const { return "SectionMatchListASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline ListASTNode * getSections() { return m_sections; }
+       inline std::string * getSourceName() { return m_source; }
+       
+protected:
+       smart_ptr<ListASTNode> m_sections;
+       smart_ptr<std::string> m_source;
+};
+
+/*!
+ * \brief AST node for a section glob.
+ *
+ * Can be assigned an include or exclude action for when this node is part of a
+ * SectionMatchListASTNode.
+ */
+class SectionASTNode : public ASTNode
+{
+public:
+       //! Possible actions for a section match list.
+       typedef enum
+       {
+               kInclude,       //!< Include sections matched by this node.
+               kExclude        //!< Exclude sections matched by this node.
+       } match_action_t;
+       
+public:
+       SectionASTNode(std::string * name)
+       :       ASTNode(), m_action(kInclude), m_name(name), m_source()
+       {
+       }
+       
+       SectionASTNode(std::string * name, match_action_t action)
+       :       ASTNode(), m_action(action), m_name(name), m_source()
+       {
+       }
+       
+       SectionASTNode(std::string * name, std::string * source)
+       :       ASTNode(), m_action(kInclude), m_name(name), m_source(source)
+       {
+       }
+       
+       SectionASTNode(const SectionASTNode & other);
+       
+       virtual ASTNode * clone() const { return new SectionASTNode(*this); }
+
+       virtual std::string nodeName() const { return "SectionASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline match_action_t getAction() { return m_action; }
+       inline std::string * getSectionName() { return m_name; }
+       inline std::string * getSourceName() { return m_source; }
+       
+protected:
+       match_action_t m_action;
+       smart_ptr<std::string> m_name;
+       smart_ptr<std::string> m_source;
+};
+
+/*!
+ *
+ */
+class SymbolASTNode : public ASTNode
+{
+public:
+       SymbolASTNode()
+       :       ASTNode(), m_symbol(), m_source()
+       {
+       }
+
+       SymbolASTNode(std::string * symbol, std::string * source=0)
+       :       ASTNode(), m_symbol(symbol), m_source(source)
+       {
+       }
+       
+       SymbolASTNode(const SymbolASTNode & other);
+       
+       virtual ASTNode * clone() const { return new SymbolASTNode(*this); }
+
+       virtual std::string nodeName() const { return "SymbolASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline void setSymbolName(std::string * symbol) { m_symbol = symbol; }
+       inline std::string * getSymbolName() { return m_symbol; }
+       
+       inline void setSource(std::string * source) { m_source = source; }
+       inline std::string * getSource() { return m_source; }
+
+protected:
+       smart_ptr<std::string> m_symbol;        //!< Required.
+       smart_ptr<std::string> m_source;        //!< Optional, may be NULL;
+};
+
+/*!
+ * If the end of the range is NULL, then only a single address was specified.
+ */
+class AddressRangeASTNode : public ASTNode
+{
+public:
+       AddressRangeASTNode()
+       :       ASTNode(), m_begin(), m_end()
+       {
+       }
+       
+       AddressRangeASTNode(ASTNode * begin, ASTNode * end)
+       :       ASTNode(), m_begin(begin), m_end(end)
+       {
+       }
+       
+       AddressRangeASTNode(const AddressRangeASTNode & other);
+       
+       virtual ASTNode * clone() const { return new AddressRangeASTNode(*this); }
+
+       virtual std::string nodeName() const { return "AddressRangeASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline void setBegin(ASTNode * begin) { m_begin = begin; }
+       inline ASTNode * getBegin() { return m_begin; }
+       
+       inline void setEnd(ASTNode * end) { m_end = end; }
+       inline ASTNode * getEnd() { return m_end; }
+       
+protected:
+       smart_ptr<ASTNode> m_begin;
+       smart_ptr<ASTNode> m_end;
+};
+
+/*!
+ *
+ */
+class NaturalLocationASTNode : public ASTNode
+{
+public:
+       NaturalLocationASTNode()
+       :       ASTNode()
+       {
+       }
+       
+       NaturalLocationASTNode(const NaturalLocationASTNode & other)
+       :       ASTNode(other)
+       {
+       }
+       
+       virtual ASTNode * clone() const { return new NaturalLocationASTNode(*this); }
+
+       virtual std::string nodeName() const { return "NaturalLocationASTNode"; }
+};
+
+/*!
+ *
+ */
+class FromStatementASTNode : public StatementASTNode
+{
+public:
+       FromStatementASTNode() : StatementASTNode() {}
+       FromStatementASTNode(std::string * source, ListASTNode * statements);
+       FromStatementASTNode(const FromStatementASTNode & other);
+       
+       virtual ASTNode * clone() const { return new FromStatementASTNode(*this); }
+
+       virtual std::string nodeName() const { return "FromStatementASTNode"; }
+       
+       virtual void printTree(int indent) const;
+       
+       inline void setSourceName(std::string * source) { m_source = source; }
+       inline std::string * getSourceName() { return m_source; }
+       
+       inline void setStatements(ListASTNode * statements) { m_statements = statements; }
+       inline ListASTNode * getStatements() { return m_statements; }
+
+protected:
+       smart_ptr<std::string> m_source;
+       smart_ptr<ListASTNode> m_statements;
+};
+
+}; // namespace elftosb
+
+#endif // _ElftosbAST_h_
diff --git a/tools/elftosb/elftosb2/ElftosbErrors.h b/tools/elftosb/elftosb2/ElftosbErrors.h
new file mode 100644 (file)
index 0000000..abb546a
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * File:       ConversionController.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_ElftosbErrors_h_)
+#define _ElftosbErrors_h_
+
+#include <string>
+#include <stdexcept>
+
+namespace elftosb
+{
+
+/*!
+ * \brief A semantic error discovered while processing the command file AST.
+ */
+class semantic_error : public std::runtime_error
+{
+public:
+       explicit semantic_error(const std::string & msg)
+       :       std::runtime_error(msg)
+       {}
+};
+
+}; // namespace elftosb
+
+#endif // _ElftosbErrors_h_
diff --git a/tools/elftosb/elftosb2/ElftosbLexer.cpp b/tools/elftosb/elftosb2/ElftosbLexer.cpp
new file mode 100644 (file)
index 0000000..b1ba327
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * File:       ElftosbLexer.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#include "ElftosbLexer.h"
+#include <algorithm>
+#include "HexValues.h"
+
+using namespace elftosb;
+
+ElftosbLexer::ElftosbLexer(istream & inputStream)
+:      yyFlexLexer(&inputStream), m_line(1), m_blob(0), m_blobFirstLine(0)
+{
+}
+
+void ElftosbLexer::getSymbolValue(YYSTYPE * value)
+{
+       if (!value)
+       {
+               return;
+       }
+       *value = m_symbolValue;
+}
+
+void ElftosbLexer::addSourceName(std::string * ident)
+{
+       m_sources.push_back(*ident);
+}
+
+bool ElftosbLexer::isSourceName(std::string * ident)
+{
+       string_vector_t::iterator it = find(m_sources.begin(), m_sources.end(), *ident);
+       return it != m_sources.end();
+}
+
+void ElftosbLexer::LexerError(const char * msg)
+{
+       throw elftosb::lexical_error(msg);
+}
+
+//! Reads the \a in string and writes to the \a out string. These strings can be the same
+//! string since the read head is always in front of the write head.
+//!
+//! \param[in] in Input string containing C-style escape sequences.
+//! \param[out] out Output string. All escape sequences in the input string have been converted
+//!            to the actual characters. May point to the same string as \a in.
+//! \return The length of the resulting \a out string. This length is necessary because
+//!            the string may have contained escape sequences that inserted null characters.
+int ElftosbLexer::processStringEscapes(const char * in, char * out)
+{
+       int count = 0;
+       while (*in)
+       {
+               switch (*in)
+               {
+                       case '\\':
+                       {
+                               // start of an escape sequence
+                               char c = *++in;
+                               switch (c)
+                               {
+                                       case 0: // end of the string, bail
+                                               break;
+                                       case 'x':
+                                       {
+                                               // start of a hex char escape sequence
+                                               
+                                               // read high and low nibbles, checking for end of string
+                                               char hi = *++in;
+                                               if (hi == 0) break;
+                                               char lo = *++in;
+                                               if (lo == 0) break;
+                                               
+                                               if (isHexDigit(hi) && isHexDigit(lo))
+                                               {
+                                                       if (hi >= '0' && hi <= '9')
+                                                               c = (hi - '0') << 4;
+                                                       else if (hi >= 'A' && hi <= 'F')
+                                                               c = (hi - 'A' + 10) << 4;
+                                                       else if (hi >= 'a' && hi <= 'f')
+                                                               c = (hi - 'a' + 10) << 4;
+                                                       
+                                                       if (lo >= '0' && lo <= '9')
+                                                               c |= lo - '0';
+                                                       else if (lo >= 'A' && lo <= 'F')
+                                                               c |= lo - 'A' + 10;
+                                                       else if (lo >= 'a' && lo <= 'f')
+                                                               c |= lo - 'a' + 10;
+                                                               
+                                                       *out++ = c;
+                                                       count++;
+                                               }
+                                               else
+                                               {
+                                                       // not hex digits, the \x must have wanted an 'x' char
+                                                       *out++ = 'x';
+                                                       *out++ = hi;
+                                                       *out++ = lo;
+                                                       count += 3;
+                                               }
+                                               break;
+                                       }
+                                       case 'n':
+                                               *out++ = '\n';
+                                               count++;
+                                               break;
+                                       case 't':
+                                               *out++ = '\t';
+                                               count++;
+                                               break;
+                                       case 'r':
+                                               *out++ = '\r';
+                                               count++;
+                                               break;
+                                       case 'b':
+                                               *out++ = '\b';
+                                               count++;
+                                               break;
+                                       case 'f':
+                                               *out++ = '\f';
+                                               count++;
+                                               break;
+                                       case '0':
+                                               *out++ = '\0';
+                                               count++;
+                                               break;
+                                       default:
+                                               *out++ = c;
+                                               count++;
+                                               break;
+                               }
+                               break;
+                       }
+                       
+                       default:
+                               // copy all other chars directly
+                               *out++ = *in++;
+                               count++;
+               }
+       }
+       
+       // place terminating null char on output
+       *out = 0;
+       return count;
+}
+
+
diff --git a/tools/elftosb/elftosb2/ElftosbLexer.h b/tools/elftosb/elftosb2/ElftosbLexer.h
new file mode 100644 (file)
index 0000000..04a16f9
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * File:       ElftosbLexer.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+// This header just wraps the standard flex C++ header to make it easier to include
+// without having to worry about redefinitions of the class name every time.
+
+#if !defined(_ElftosbLexer_h_)
+#define _ElftosbLexer_h_
+
+#include "ElftosbAST.h"
+#include "FlexLexer.h"
+#include "elftosb_parser.tab.hpp"
+#include <vector>
+#include <string>
+#include <stdexcept>
+#include "Blob.h"
+
+using namespace std;
+
+namespace elftosb
+{
+
+/*!
+ * \brief Exception class for syntax errors.
+ */
+class syntax_error : public std::runtime_error
+{
+public:
+       explicit syntax_error(const std::string & __arg) : std::runtime_error(__arg) {}
+};
+
+/*!
+ * \brief Exception class for lexical errors.
+ */
+class lexical_error : public std::runtime_error
+{
+public:
+       explicit lexical_error(const std::string & __arg) : std::runtime_error(__arg) {}
+};
+
+/*!
+ * \brief Lexical scanner class for elftosb command files.
+ *
+ * This class is a subclass of the standard C++ lexer class produced by
+ * Flex. It's primary purpose is to provide a clean way to report values
+ * for symbols, without using the yylval global. This is necessary because
+ * the parser produced by Bison is a "pure" parser.
+ *
+ * In addition, this class manages a list of source names generated by
+ * parsing. The lexer uses this list to determine if an identifier is
+ * a source name or a constant identifier.
+ */
+class ElftosbLexer : public yyFlexLexer
+{
+public:
+       //! \brief Constructor.
+       ElftosbLexer(istream & inputStream);
+
+       //! \brief Lexer interface. Returns one token.
+       virtual int yylex();
+       
+       //! \brief Returns the value for the most recently produced token in \a value.
+       virtual void getSymbolValue(YYSTYPE * value);
+       
+       //! \brief Returns the current token's location in \a loc.
+       inline token_loc_t & getLocation() { return m_location; }
+       
+       //! \name Source names
+       //@{
+       void addSourceName(std::string * ident);
+       bool isSourceName(std::string * ident);
+       //@}
+
+protected:
+       YYSTYPE m_symbolValue;  //!< Value for the current token.
+       int m_line;     //!< Current line number.
+       token_loc_t m_location; //!< Location for the current token.
+       Blob * m_blob;  //!< The binary object value as its being constructed.
+       int m_blobFirstLine;    //!< Line number for the first character of a blob.
+
+       typedef std::vector<std::string> string_vector_t;
+       string_vector_t m_sources;      //!< Vector of source identifiers;
+       
+       //! \brief Throw an elftosb::lexical_error exception.
+       virtual void LexerError(const char * msg);
+
+       //! \brief Process a string containing escape sequences.
+       int processStringEscapes(const char * in, char * out);
+};
+
+}; // namespace elftosb
+
+#endif // _ElftosbLexer_h_
diff --git a/tools/elftosb/elftosb2/EncoreBootImageGenerator.cpp b/tools/elftosb/elftosb2/EncoreBootImageGenerator.cpp
new file mode 100644 (file)
index 0000000..9bb65c2
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * File:       EncoreBootImageGenerator.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "EncoreBootImageGenerator.h"
+#include "Logging.h"
+
+#define kFlagsOption "flags"
+#define kSectionFlagsOption "sectionFlags"
+#define kProductVersionOption "productVersion"
+#define kComponentVersionOption "componentVersion"
+#define kAlignmentOption "alignment"
+#define kCleartextOption "cleartext"
+
+using namespace elftosb;
+
+BootImage * EncoreBootImageGenerator::generate()
+{
+       EncoreBootImage * image = new EncoreBootImage();
+       
+       // process each output section
+       section_vector_t::iterator it = m_sections.begin();
+       for (; it != m_sections.end(); ++it)
+       {
+               OutputSection * section = *it;
+               
+               OperationSequenceSection * opSection = dynamic_cast<OperationSequenceSection*>(section);
+               if (opSection)
+               {
+                       processOperationSection(opSection, image);
+                       continue;
+               }
+               
+               BinaryDataSection * dataSection = dynamic_cast<BinaryDataSection*>(section);
+               if (dataSection)
+               {
+                       processDataSection(dataSection, image);
+                       continue;
+               }
+               
+               Log::log(Logger::WARNING, "warning: unexpected output section type\n");
+       }
+       
+       // handle global options that affect the image
+       processOptions(image);
+       
+       return image;
+}
+
+void EncoreBootImageGenerator::processOptions(EncoreBootImage * image)
+{
+       // bail if no option context was set
+       if (!m_options)
+       {
+               return;
+       }
+       
+       if (m_options->hasOption(kFlagsOption))
+       {
+        const IntegerValue * intValue = dynamic_cast<const IntegerValue *>(m_options->getOption(kFlagsOption));
+               if (intValue)
+               {
+                       image->setFlags(intValue->getValue());
+               }
+        else
+        {
+            Log::log(Logger::WARNING, "warning: flags option is an unexpected type\n");
+        }
+       }
+       
+    // handle common options
+       processVersionOptions(image);
+       processDriveTagOption(image);
+}
+
+void EncoreBootImageGenerator::processSectionOptions(EncoreBootImage::Section * imageSection, OutputSection * modelSection)
+{
+       // Get options context for this output section.
+       const OptionContext * context = modelSection->getOptions();
+       if (!context)
+       {
+               return;
+       }
+       
+       // Check for and handle "sectionFlags" option.
+       if (context->hasOption(kSectionFlagsOption))
+       {
+               const Value * value = context->getOption(kSectionFlagsOption);
+        const IntegerValue * intValue = dynamic_cast<const IntegerValue *>(value);
+               if (intValue)
+               {
+                       // set explicit flags for this section
+                       imageSection->setFlags(intValue->getValue());
+               }
+        else
+        {
+            Log::log(Logger::WARNING, "warning: sectionFlags option is an unexpected type\n");
+        }
+       }
+       
+       // Check for and handle "alignment" option.
+       if (context->hasOption(kAlignmentOption))
+       {
+               const Value * value = context->getOption(kAlignmentOption);
+        const IntegerValue * intValue = dynamic_cast<const IntegerValue *>(value);
+               if (intValue)
+               {
+                       // verify alignment value
+                       if (intValue->getValue() < EncoreBootImage::BOOT_IMAGE_MINIMUM_SECTION_ALIGNMENT)
+                       {
+                               Log::log(Logger::WARNING, "warning: alignment option value must be 16 or greater\n");
+                       }
+                       
+                       imageSection->setAlignment(intValue->getValue());
+               }
+        else
+        {
+            Log::log(Logger::WARNING, "warning: alignment option is an unexpected type\n");
+        }
+       }
+       
+       // Check for and handle "cleartext" option.
+       if (context->hasOption(kCleartextOption))
+       {
+               const Value * value = context->getOption(kCleartextOption);
+        const IntegerValue * intValue = dynamic_cast<const IntegerValue *>(value);
+               if (intValue)
+               {
+                       bool leaveUnencrypted = intValue->getValue() != 0;
+                       imageSection->setLeaveUnencrypted(leaveUnencrypted);
+               }
+        else
+        {
+            Log::log(Logger::WARNING, "warning: cleartext option is an unexpected type\n");
+        }
+       }
+}
+
+void EncoreBootImageGenerator::processOperationSection(OperationSequenceSection * section, EncoreBootImage * image)
+{
+       EncoreBootImage::BootSection * newSection = new EncoreBootImage::BootSection(section->getIdentifier());
+       
+       OperationSequence & sequence = section->getSequence();
+       OperationSequence::iterator_t it = sequence.begin();
+       for (; it != sequence.end(); ++it)
+       {
+               Operation * op = *it;
+               
+               LoadOperation * loadOp = dynamic_cast<LoadOperation*>(op);
+               if (loadOp)
+               {
+                       processLoadOperation(loadOp, newSection);
+                       continue;
+               }
+               
+               ExecuteOperation * execOp = dynamic_cast<ExecuteOperation*>(op);
+               if (execOp)
+               {
+                       processExecuteOperation(execOp, newSection);
+                       continue;
+               }
+               
+               BootModeOperation * modeOp = dynamic_cast<BootModeOperation*>(op);
+               if (modeOp)
+               {
+                       processBootModeOperation(modeOp, newSection);
+                       continue;
+               }
+               
+               Log::log(Logger::WARNING, "warning: unexpected operation type\n");
+       }
+       
+       // Deal with options that apply to sections.
+       processSectionOptions(newSection, section);
+       
+       // add the boot section to the image
+       image->addSection(newSection);
+}
+
+void EncoreBootImageGenerator::processLoadOperation(LoadOperation * op, EncoreBootImage::BootSection * section)
+{
+       DataSource * source = op->getSource();
+       DataTarget * target = op->getTarget();
+       
+       // other sources get handled the same way
+       unsigned segmentCount = source->getSegmentCount();
+       unsigned index = 0;
+       for (; index < segmentCount; ++index)
+       {
+               DataSource::Segment * segment = source->getSegmentAt(index);
+               DataTarget::AddressRange range = target->getRangeForSegment(*source, *segment);
+               unsigned rangeLength = range.m_end - range.m_begin;
+               
+               // handle a pattern segment as a special case to create a fill command
+               DataSource::PatternSegment * patternSegment = dynamic_cast<DataSource::PatternSegment*>(segment);
+               if (patternSegment)
+               {
+                       SizedIntegerValue & pattern = patternSegment->getPattern();
+                       
+                       EncoreBootImage::FillCommand * command = new EncoreBootImage::FillCommand();
+                       command->setAddress(range.m_begin);
+                       command->setFillCount(rangeLength);
+                       setFillPatternFromValue(*command, pattern);
+                       
+                       section->addCommand(command);
+                       continue;
+               }
+               
+               // get the data from the segment
+               uint8_t * data = new uint8_t[rangeLength];
+               segment->getData(0, rangeLength, data);
+               
+               // create the boot command
+               EncoreBootImage::LoadCommand * command = new EncoreBootImage::LoadCommand();
+               command->setData(data, rangeLength); // Makes a copy of the data buffer.
+               command->setLoadAddress(range.m_begin);
+               command->setDCD(op->isDCDLoad());
+               
+               section->addCommand(command);
+        
+        // Free the segment buffer.
+        delete [] data;
+       }
+}
+
+void EncoreBootImageGenerator::setFillPatternFromValue(EncoreBootImage::FillCommand & command, SizedIntegerValue & pattern)
+{
+       uint32_t u32PatternValue = pattern.getValue() & pattern.getWordSizeMask();
+       switch (pattern.getWordSize())
+       {
+               case kWordSize:
+               {
+                       command.setPattern(u32PatternValue);
+                       break;
+               }
+               
+               case kHalfWordSize:
+               {
+                       uint16_t u16PatternValue = static_cast<uint16_t>(u32PatternValue);
+                       command.setPattern(u16PatternValue);
+                       break;
+               }
+               
+               case kByteSize:
+               {
+                       uint8_t u8PatternValue = static_cast<uint8_t>(u32PatternValue);
+                       command.setPattern(u8PatternValue);
+               }
+       }
+}
+
+void EncoreBootImageGenerator::processExecuteOperation(ExecuteOperation * op, EncoreBootImage::BootSection * section)
+{
+       DataTarget * target = op->getTarget();
+       uint32_t arg = static_cast<uint32_t>(op->getArgument());
+       
+       EncoreBootImage::JumpCommand * command;
+       switch (op->getExecuteType())
+       {
+               case ExecuteOperation::kJump:
+                       command = new EncoreBootImage::JumpCommand();
+                       break;
+               
+               case ExecuteOperation::kCall:
+                       command = new EncoreBootImage::CallCommand();
+                       break;
+       }
+       
+       command->setAddress(target->getBeginAddress());
+       command->setArgument(arg);
+       command->setIsHAB(op->isHAB());
+       
+       section->addCommand(command);
+}
+
+void EncoreBootImageGenerator::processBootModeOperation(BootModeOperation * op, EncoreBootImage::BootSection * section)
+{
+       EncoreBootImage::ModeCommand * command = new EncoreBootImage::ModeCommand();
+       command->setBootMode(op->getBootMode());
+       
+       section->addCommand(command);
+}
+
+void EncoreBootImageGenerator::processDataSection(BinaryDataSection * section, EncoreBootImage * image)
+{
+       EncoreBootImage::DataSection * dataSection = new EncoreBootImage::DataSection(section->getIdentifier());
+       dataSection->setData(section->getData(), section->getLength());
+       
+       // Handle alignment option.
+       processSectionOptions(dataSection, section);
+       
+       image->addSection(dataSection);
+}
+
diff --git a/tools/elftosb/elftosb2/EncoreBootImageGenerator.h b/tools/elftosb/elftosb2/EncoreBootImageGenerator.h
new file mode 100644 (file)
index 0000000..f0466bb
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * File:       EncoreBootImageGenerator.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_EncoreBootImageGenerator_h_)
+#define _EncoreBootImageGenerator_h_
+
+#include "BootImageGenerator.h"
+#include "EncoreBootImage.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Generator for Encore boot images.
+ *
+ * Takes the abstract model of the output file and processes it into a
+ * concrete boot image for the STMP37xx.
+ *
+ * In order to enable full i.mx28 support, you must call the setSupportHAB() method and
+ * pass true.
+ */
+class EncoreBootImageGenerator : public BootImageGenerator
+{
+public:
+       //! \brief Default constructor.
+       EncoreBootImageGenerator() : BootImageGenerator() {}
+       
+       //! \brief Builds the resulting boot image from previously added output sections.
+       virtual BootImage * generate();
+    
+    //! \brief Enable or disable HAB support.
+    void setSupportHAB(bool supportHAB) { m_supportHAB = supportHAB; }
+       
+protected:
+    
+    bool m_supportHAB;  //!< True if HAB features are enabled.
+    
+       void processOptions(EncoreBootImage * image);
+       void processSectionOptions(EncoreBootImage::Section * imageSection, OutputSection * modelSection);
+       
+       void processOperationSection(OperationSequenceSection * section, EncoreBootImage * image);
+       void processDataSection(BinaryDataSection * section, EncoreBootImage * image);
+
+       void processLoadOperation(LoadOperation * op, EncoreBootImage::BootSection * section);
+       void processExecuteOperation(ExecuteOperation * op, EncoreBootImage::BootSection * section);
+       void processBootModeOperation(BootModeOperation * op, EncoreBootImage::BootSection * section);
+       
+       void setFillPatternFromValue(EncoreBootImage::FillCommand & command, SizedIntegerValue & pattern);
+};
+
+}; // namespace elftosb
+
+#endif // _EncoreBootImageGenerator_h_
+
diff --git a/tools/elftosb/elftosb2/FlexLexer.h b/tools/elftosb/elftosb2/FlexLexer.h
new file mode 100644 (file)
index 0000000..8b26ef2
--- /dev/null
@@ -0,0 +1,208 @@
+// -*-C++-*-
+// FlexLexer.h -- define interfaces for lexical analyzer classes generated
+// by flex
+
+// Copyright (c) 1993 The Regents of the University of California.
+// All rights reserved.
+//
+// This code is derived from software contributed to Berkeley by
+// Kent Williams and Tom Epperly.
+//
+//  Redistribution and use in source and binary forms, with or without
+//  modification, are permitted provided that the following conditions
+//  are met:
+
+//  1. Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//  2. Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+
+//  Neither the name of the University nor the names of its contributors
+//  may be used to endorse or promote products derived from this software
+//  without specific prior written permission.
+
+//  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+//  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+//  PURPOSE.
+
+// This file defines FlexLexer, an abstract class which specifies the
+// external interface provided to flex C++ lexer objects, and yyFlexLexer,
+// which defines a particular lexer class.
+//
+// If you want to create multiple lexer classes, you use the -P flag
+// to rename each yyFlexLexer to some other xxFlexLexer.  You then
+// include <FlexLexer.h> in your other sources once per lexer class:
+//
+//     #undef yyFlexLexer
+//     #define yyFlexLexer xxFlexLexer
+//     #include <FlexLexer.h>
+//
+//     #undef yyFlexLexer
+//     #define yyFlexLexer zzFlexLexer
+//     #include <FlexLexer.h>
+//     ...
+
+#ifndef __FLEX_LEXER_H
+// Never included before - need to define base class.
+#define __FLEX_LEXER_H
+
+#include <iostream>
+#  ifndef FLEX_STD
+#    define FLEX_STD std::
+#  endif
+
+extern "C++" {
+
+struct yy_buffer_state;
+typedef int yy_state_type;
+
+class FlexLexer {
+public:
+       virtual ~FlexLexer()    { }
+
+       const char* YYText() const      { return yytext; }
+       int YYLeng()    const   { return yyleng; }
+
+       virtual void
+               yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
+       virtual struct yy_buffer_state*
+               yy_create_buffer( FLEX_STD istream* s, int size ) = 0;
+       virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
+       virtual void yyrestart( FLEX_STD istream* s ) = 0;
+
+       virtual int yylex() = 0;
+
+       // Call yylex with new input/output sources.
+       int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 )
+               {
+               switch_streams( new_in, new_out );
+               return yylex();
+               }
+
+       // Switch to new input/output streams.  A nil stream pointer
+       // indicates "keep the current one".
+       virtual void switch_streams( FLEX_STD istream* new_in = 0,
+                                       FLEX_STD ostream* new_out = 0 ) = 0;
+
+       int lineno() const              { return yylineno; }
+
+       int debug() const               { return yy_flex_debug; }
+       void set_debug( int flag )      { yy_flex_debug = flag; }
+
+protected:
+       char* yytext;
+       int yyleng;
+       int yylineno;           // only maintained if you use %option yylineno
+       int yy_flex_debug;      // only has effect with -d or "%option debug"
+};
+
+}
+#endif // FLEXLEXER_H
+
+//#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
+// had to disable the 'defined(yyFlexLexer)' part because it was causing duplicate class defs
+#if ! defined(yyFlexLexerOnce)
+// Either this is the first time through (yyFlexLexerOnce not defined),
+// or this is a repeated include to define a different flavor of
+// yyFlexLexer, as discussed in the flex manual.
+#define yyFlexLexerOnce
+
+extern "C++" {
+
+class yyFlexLexer : public FlexLexer {
+public:
+       // arg_yyin and arg_yyout default to the cin and cout, but we
+       // only make that assignment when initializing in yylex().
+       yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 );
+
+       virtual ~yyFlexLexer();
+
+       void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
+       struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size );
+       void yy_delete_buffer( struct yy_buffer_state* b );
+       void yyrestart( FLEX_STD istream* s );
+
+       void yypush_buffer_state( struct yy_buffer_state* new_buffer );
+       void yypop_buffer_state();
+
+       virtual int yylex();
+       virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 );
+       virtual int yywrap();
+
+protected:
+       virtual int LexerInput( char* buf, int max_size );
+       virtual void LexerOutput( const char* buf, int size );
+       virtual void LexerError( const char* msg );
+
+       void yyunput( int c, char* buf_ptr );
+       int yyinput();
+
+       void yy_load_buffer_state();
+       void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s );
+       void yy_flush_buffer( struct yy_buffer_state* b );
+
+       int yy_start_stack_ptr;
+       int yy_start_stack_depth;
+       int* yy_start_stack;
+
+       void yy_push_state( int new_state );
+       void yy_pop_state();
+       int yy_top_state();
+
+       yy_state_type yy_get_previous_state();
+       yy_state_type yy_try_NUL_trans( yy_state_type current_state );
+       int yy_get_next_buffer();
+
+       FLEX_STD istream* yyin; // input source for default LexerInput
+       FLEX_STD ostream* yyout;        // output sink for default LexerOutput
+
+       // yy_hold_char holds the character lost when yytext is formed.
+       char yy_hold_char;
+
+       // Number of characters read into yy_ch_buf.
+       int yy_n_chars;
+
+       // Points to current character in buffer.
+       char* yy_c_buf_p;
+
+       int yy_init;            // whether we need to initialize
+       int yy_start;           // start state number
+
+       // Flag which is used to allow yywrap()'s to do buffer switches
+       // instead of setting up a fresh yyin.  A bit of a hack ...
+       int yy_did_buffer_switch_on_eof;
+
+
+       size_t yy_buffer_stack_top; /**< index of top of stack. */
+       size_t yy_buffer_stack_max; /**< capacity of stack. */
+       struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */
+       void yyensure_buffer_stack(void);
+
+       // The following are not always needed, but may be depending
+       // on use of certain flex features (like REJECT or yymore()).
+
+       yy_state_type yy_last_accepting_state;
+       char* yy_last_accepting_cpos;
+
+       yy_state_type* yy_state_buf;
+       yy_state_type* yy_state_ptr;
+
+       char* yy_full_match;
+       int* yy_full_state;
+       int yy_full_lp;
+
+       int yy_lp;
+       int yy_looking_for_trail_begin;
+
+       int yy_more_flag;
+       int yy_more_len;
+       int yy_more_offset;
+       int yy_prev_more_offset;
+};
+
+}
+
+#endif // yyFlexLexer || ! yyFlexLexerOnce
+
diff --git a/tools/elftosb/elftosb2/elftosb.cpp b/tools/elftosb/elftosb2/elftosb.cpp
new file mode 100644 (file)
index 0000000..f358bd9
--- /dev/null
@@ -0,0 +1,700 @@
+/*
+ * File:       elftosb.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "stdafx.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <stdlib.h>
+#include <stdexcept>
+#include "ConversionController.h"
+#include "options.h"
+#include "Version.h"
+#include "EncoreBootImage.h"
+#include "smart_ptr.h"
+#include "Logging.h"
+#include "EncoreBootImageGenerator.h"
+#include "SearchPath.h"
+#include "format_string.h"
+
+//! An array of strings.
+typedef std::vector<std::string> string_vector_t;
+
+//! The tool's name.
+const char k_toolName[] = "elftosb";
+
+//! Current version number for the tool.
+const char k_version[] = "2.6.1";
+
+//! Copyright string.
+const char k_copyright[] = "Copyright (c) 2004-2010 Freescale Semiconductor, Inc.\nAll rights reserved.";
+
+static const char * k_optionsDefinition[] = {
+       "?|help",
+       "v|version",
+       "f:chip-family <family>",
+       "c:command <file>",
+       "o:output <file>",
+       "P:product <version>",
+       "C:component <version>",
+       "k:key <file>",
+       "z|zero-key",
+       "D:define <const>",
+       "O:option <option>",
+       "d|debug",
+       "q|quiet",
+       "V|verbose",
+       "p:search-path <path>",
+       NULL
+};
+
+//! Help string.
+const char k_usageText[] = "\nOptions:\n\
+  -?/--help                    Show this help\n\
+  -v/--version                 Display tool version\n\
+  -f/--chip-family <family>    Select the chip family (default is 37xx)\n\
+  -c/--command <file>          Use this command file\n\
+  -o/--output <file>           Write output to this file\n\
+  -p/--search-path <path>      Add a search path used to find input files\n\
+  -P/--product <version        Set product version\n\
+  -C/--component <version>     Set component version\n\
+  -k/--key <file>              Add OTP key, enable encryption\n\
+  -z/--zero-key                Add default key of all zeroes\n\
+  -D/--define <const>=<int>    Define or override a constant value\n\
+  -O/--option <name>=<value>   Set or override a processing option\n\
+  -d/--debug                   Enable debug output\n\
+  -q/--quiet                   Output only warnings and errors\n\
+  -V/--verbose                 Print extra detailed log information\n\n";
+
+// prototypes
+int main(int argc, char* argv[], char* envp[]);
+
+/*!
+ * \brief Class that encapsulates the elftosb tool.
+ *
+ * A single global logger instance is created during object construction. It is
+ * never freed because we need it up to the last possible minute, when an
+ * exception could be thrown.
+ */
+class elftosbTool
+{
+protected:
+       //! Supported chip families.
+       enum chip_family_t
+       {
+               k37xxFamily,    //!< 37xx series.
+               kMX28Family,    //!< Catskills series.
+       };
+       
+       /*!
+        * \brief A structure describing an entry in the table of chip family names.
+        */
+       struct FamilyNameTableEntry
+       {
+               const char * const name;
+               chip_family_t family;
+       };
+       
+       //! \brief Table that maps from family name strings to chip family constants.
+       static const FamilyNameTableEntry kFamilyNameTable[];
+       
+       int m_argc;                                                     //!< Number of command line arguments.
+       char ** m_argv;                                         //!< String value for each command line argument.
+       StdoutLogger * m_logger;                        //!< Singleton logger instance.
+       string_vector_t m_keyFilePaths;         //!< Paths to OTP key files.
+       string_vector_t m_positionalArgs;       //!< Arguments coming after explicit options.
+       bool m_isVerbose;                                       //!< Whether the verbose flag was turned on.
+       bool m_useDefaultKey;                                   //!< Include a default (zero) crypto key.
+       const char * m_commandFilePath;         //!< Path to the elftosb command file.
+       const char * m_outputFilePath;          //!< Path to the output .sb file.
+       const char * m_searchPath;                      //!< Optional search path for input files.
+       elftosb::version_t m_productVersion;    //!< Product version specified on command line.
+       elftosb::version_t m_componentVersion;  //!< Component version specified on command line.
+       bool m_productVersionSpecified;         //!< True if the product version was specified on the command line.
+       bool m_componentVersionSpecified;               //!< True if the component version was specified on the command line.
+       chip_family_t m_family;                         //!< Chip family that the output file is formatted for.
+       elftosb::ConversionController m_controller;     //!< Our conversion controller instance.
+               
+public:
+       /*!
+        * Constructor.
+        *
+        * Creates the singleton logger instance.
+        */
+       elftosbTool(int argc, char * argv[])
+       :       m_argc(argc),
+               m_argv(argv),
+               m_logger(0),
+               m_keyFilePaths(),
+               m_positionalArgs(),
+               m_isVerbose(false),
+               m_useDefaultKey(false),
+               m_commandFilePath(NULL),
+               m_outputFilePath(NULL),
+               m_searchPath(NULL),
+               m_productVersion(),
+               m_componentVersion(),
+               m_productVersionSpecified(false),
+               m_componentVersionSpecified(false),
+               m_family(k37xxFamily),
+               m_controller()
+       {
+               // create logger instance
+               m_logger = new StdoutLogger();
+               m_logger->setFilterLevel(Logger::INFO);
+               Log::setLogger(m_logger);
+       }
+       
+       /*!
+        * Destructor.
+        */
+       ~elftosbTool()
+       {
+       }
+       
+       /*!
+        * \brief Searches the family name table.
+        *
+        * \retval true The \a name was found in the table, and \a family is valid.
+        * \retval false No matching family name was found. The \a family argument is not modified.
+        */
+       bool lookupFamilyName(const char * name, chip_family_t * family)
+       {
+               // Create a local read-write copy of the argument string.
+               std::string familyName(name);
+               
+               // Convert the argument string to lower case for case-insensitive comparison.
+               for (int n=0; n < familyName.length(); n++)
+               {
+                       familyName[n] = tolower(familyName[n]);
+               }
+               
+        // Exit the loop if we hit the NULL terminator entry.
+               const FamilyNameTableEntry * entry = &kFamilyNameTable[0];
+               for (; entry->name; entry++)
+               {
+                       // Compare lowercased name with the table entry.
+                       if (familyName == entry->name)
+                       {
+                               *family = entry->family;
+                               return true;
+                       }
+               }
+               
+               // Failed to find a matching name.
+               return false;
+       }
+       
+       /*!
+        * Reads the command line options passed into the constructor.
+        *
+        * This method can return a return code to its caller, which will cause the
+        * tool to exit immediately with that return code value. Normally, though, it
+        * will return -1 to signal that the tool should continue to execute and
+        * all options were processed successfully.
+        *
+        * The Options class is used to parse command line options. See
+        * #k_optionsDefinition for the list of options and #k_usageText for the
+        * descriptive help for each option.
+        *
+        * \retval -1 The options were processed successfully. Let the tool run normally.
+        * \return A zero or positive result is a return code value that should be
+        *              returned from the tool as it exits immediately.
+        */
+       int processOptions()
+       {
+               Options options(*m_argv, k_optionsDefinition);
+               OptArgvIter iter(--m_argc, ++m_argv);
+               
+               // process command line options
+               int optchar;
+               const char * optarg;
+               while (optchar = options(iter, optarg))
+               {
+                       switch (optchar)
+                       {
+                               case '?':
+                                       printUsage(options);
+                                       return 0;
+                               
+                               case 'v':
+                                       printf("%s %s\n%s\n", k_toolName, k_version, k_copyright);
+                                       return 0;
+                               
+                               case 'f':
+                                       if (!lookupFamilyName(optarg, &m_family))
+                                       {
+                                               Log::log(Logger::ERROR, "error: unknown chip family '%s'\n", optarg);
+                                               printUsage(options);
+                                               return 0;
+                                       }
+                                       break;
+                                       
+                               case 'c':
+                                       m_commandFilePath = optarg;
+                                       break;
+                                       
+                               case 'o':
+                                       m_outputFilePath = optarg;
+                                       break;
+                                       
+                               case 'P':
+                                       m_productVersion.set(optarg);
+                                       m_productVersionSpecified = true;
+                                       break;
+                                       
+                               case 'C':
+                                       m_componentVersion.set(optarg);
+                                       m_componentVersionSpecified = true;
+                                       break;
+                                       
+                               case 'k':
+                                       m_keyFilePaths.push_back(optarg);
+                                       break;
+                               
+                               case 'z':
+                                       m_useDefaultKey = true;
+                                       break;
+                                       
+                               case 'D':
+                                       overrideVariable(optarg);
+                                       break;
+
+                               case 'O':
+                                       overrideOption(optarg);
+                                       break;
+                                       
+                               case 'd':
+                                       Log::getLogger()->setFilterLevel(Logger::DEBUG);
+                                       break;
+                                       
+                               case 'q':
+                                       Log::getLogger()->setFilterLevel(Logger::WARNING);
+                                       break;
+                                       
+                               case 'V':
+                                       m_isVerbose = true;
+                                       break;
+                               
+                               case 'p':
+                               {
+                                       std::string newSearchPath(optarg);
+                                       PathSearcher::getGlobalSearcher().addSearchPath(newSearchPath);
+                                       break;
+                               }
+                                       
+                               default:
+                                       Log::log(Logger::ERROR, "error: unrecognized option\n\n");
+                                       printUsage(options);
+                                       return 0;
+                       }
+               }
+               
+               // handle positional args
+               if (iter.index() < m_argc)
+               {
+                       Log::SetOutputLevel leveler(Logger::DEBUG);
+                       Log::log("positional args:\n");
+                       int i;
+                       for (i = iter.index(); i < m_argc; ++i)
+                       {
+                               Log::log("%d: %s\n", i - iter.index(), m_argv[i]);
+                               m_positionalArgs.push_back(m_argv[i]);
+                       }
+               }
+               
+               // all is well
+               return -1;
+       }
+
+       /*!
+        * Prints help for the tool.
+        */
+       void printUsage(Options & options)
+       {
+               options.usage(std::cout, "files...");
+               printf(k_usageText, k_toolName);
+       }
+       
+       /*!
+        * \brief Core of the tool.
+        *
+        * Calls processOptions() to handle command line options before performing the
+        * real work the tool does.
+        */
+       int run()
+       {
+               try
+               {
+                       // read command line options
+                       int result;
+                       if ((result = processOptions()) != -1)
+                       {
+                               return result;
+                       }
+                       
+                       // set verbose logging
+                       setVerboseLogging();
+                       
+                       // check argument values
+                       checkArguments();
+
+                       // set up the controller
+                       m_controller.setCommandFilePath(m_commandFilePath);
+                       
+                       // add external paths to controller
+                       string_vector_t::iterator it = m_positionalArgs.begin();
+                       for (; it != m_positionalArgs.end(); ++it)
+                       {
+                               m_controller.addExternalFilePath(*it);
+                       }
+                       
+                       // run conversion
+                       convert();
+               }
+               catch (std::exception & e)
+               {
+                       Log::log(Logger::ERROR, "error: %s\n", e.what());
+                       return 1;
+               }
+               catch (...)
+               {
+                       Log::log(Logger::ERROR, "error: unexpected exception\n");
+                       return 1;
+               }
+               
+               return 0;
+       }
+       
+       /*!
+        * \brief Validate arguments that can be checked.
+        * \exception std::runtime_error Thrown if an argument value fails to pass validation.
+        */
+       void checkArguments()
+       {
+               if (m_commandFilePath == NULL)
+               {
+                       throw std::runtime_error("no command file was specified");
+               }
+               if (m_outputFilePath == NULL)
+               {
+                       throw std::runtime_error("no output file was specified");
+               }
+       }
+       
+       /*!
+        * \brief Turns on verbose logging.
+        */
+       void setVerboseLogging()
+       {
+               if (m_isVerbose)
+               {
+                       // verbose only affects the INFO and DEBUG filter levels
+                       // if the user has selected quiet mode, it overrides verbose
+                       switch (Log::getLogger()->getFilterLevel())
+                       {
+                               case Logger::INFO:
+                                       Log::getLogger()->setFilterLevel(Logger::INFO2);
+                                       break;
+                               case Logger::DEBUG:
+                                       Log::getLogger()->setFilterLevel(Logger::DEBUG2);
+                                       break;
+                       }
+               }
+       }
+
+       /*!
+        * \brief Returns the integer value for a string.
+        *
+        * Metric multiplier prefixes are supported.
+        */
+       uint32_t parseIntValue(const char * value)
+       {
+               // Accept 'true'/'yes' and 'false'/'no' as integer values.
+               if ((strcmp(value, "true") == 0) || (strcmp(value, "yes") == 0))
+               {
+                       return 1;
+               }
+               else if ((strcmp(value, "false") == 0) || (strcmp(value, "no") == 0))
+               {
+                       return 0;
+               }
+               
+               uint32_t intValue = strtoul(value, NULL, 0);
+               unsigned multiplier;
+               switch (value[strlen(value) - 1])
+               {
+                       case 'G':
+                               multiplier = 1024 * 1024 * 1024;
+                               break;
+                       case 'M':
+                               multiplier = 1024 * 1024;
+                               break;
+                       case 'K':
+                               multiplier = 1024;
+                               break;
+                       default:
+                               multiplier = 1;
+               }
+               intValue *= multiplier;
+               return intValue;
+       }
+       
+       /*!
+        * \brief Parses the -D option to override a constant value.
+        */
+       void overrideVariable(const char * optarg)
+       {
+               // split optarg into two strings
+               std::string constName(optarg);
+               int i;
+               for (i=0; i < strlen(optarg); ++i)
+               {
+                       if (optarg[i] == '=')
+                       {
+                               constName.resize(i++);
+                               break;
+                       }
+               }
+               
+               uint32_t constValue = parseIntValue(&optarg[i]);
+               
+               elftosb::EvalContext & context = m_controller.getEvalContext();
+               context.setVariable(constName, constValue);
+               context.lockVariable(constName);
+       }
+
+       /*!
+        * \brief
+        */
+       void overrideOption(const char * optarg)
+       {
+               // split optarg into two strings
+               std::string optionName(optarg);
+               int i;
+               for (i=0; i < strlen(optarg); ++i)
+               {
+                       if (optarg[i] == '=')
+                       {
+                               optionName.resize(i++);
+                               break;
+                       }
+               }
+               
+               // handle quotes for option value
+               const char * valuePtr = &optarg[i];
+               bool isString = false;
+               int len;
+               if (valuePtr[0] == '"')
+               {
+                       // remember that the value is a string and get rid of the opening quote
+                       isString = true;
+                       valuePtr++;
+
+                       // remove trailing quote if present
+                       len = strlen(valuePtr);
+                       if (valuePtr[len] == '"')
+                       {
+                               len--;
+                       }
+               }
+
+               elftosb::Value * value;
+               if (isString)
+               {
+                       std::string stringValue(valuePtr);
+                       stringValue.resize(len);        // remove trailing quote
+                       value = new elftosb::StringValue(stringValue);
+               }
+               else
+               {
+                       value = new elftosb::IntegerValue(parseIntValue(valuePtr));
+               }
+
+               // Set and lock the option in the controller
+               m_controller.setOption(optionName, value);
+               m_controller.lockOption(optionName);
+       }
+       
+       /*!
+        * \brief Do the conversion.
+        * \exception std::runtime_error This exception is thrown if the conversion controller does
+        *              not produce a boot image, or if the output file cannot be opened. Other errors
+        *              internal to the conversion controller may also produce this exception.
+        */
+       void convert()
+       {
+               // create a generator for the chosen chip family
+               smart_ptr<elftosb::BootImageGenerator> generator;
+               switch (m_family)
+               {
+                       case k37xxFamily:
+                               generator = new elftosb::EncoreBootImageGenerator;
+                               elftosb::g_enableHABSupport = false;
+                               break;
+
+                       case kMX28Family:
+                               generator = new elftosb::EncoreBootImageGenerator;
+                               elftosb::g_enableHABSupport = true;
+                               break;
+               }
+               
+               // process input and get a boot image
+               m_controller.run();
+               smart_ptr<elftosb::BootImage> image = m_controller.generateOutput(generator);
+               if (!image)
+               {
+                       throw std::runtime_error("failed to produce output!");
+               }
+               
+               // set version numbers if they were provided on the command line
+               if (m_productVersionSpecified)
+               {
+                       image->setProductVersion(m_productVersion);
+               }
+               if (m_componentVersionSpecified)
+               {
+                       image->setComponentVersion(m_componentVersion);
+               }
+               
+               // special handling for each family
+               switch (m_family)
+               {
+                       case k37xxFamily:
+                       case kMX28Family:
+                       {
+                               // add OTP keys
+                               elftosb::EncoreBootImage * encoreImage = dynamic_cast<elftosb::EncoreBootImage*>(image.get());
+                               if (encoreImage)
+                               {
+                                       // add keys
+                                       addCryptoKeys(encoreImage);
+                                       
+                                       // print debug image
+                                       encoreImage->debugPrint();
+                               }
+                               break;
+                       }
+               }
+               
+               // write output
+               std::ofstream outputStream(m_outputFilePath, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
+               if (outputStream.is_open())
+               {
+                       image->writeToStream(outputStream);
+               }
+               else
+               {
+                       throw std::runtime_error(format_string("could not open output file %s", m_outputFilePath));
+               }
+       }
+       
+       /*!
+        * \brief
+        */
+       void addCryptoKeys(elftosb::EncoreBootImage * encoreImage)
+       {
+               string_vector_t::iterator it = m_keyFilePaths.begin();
+               for (; it != m_keyFilePaths.end(); ++it)
+               {
+                       std::string & keyPath = *it;
+                       
+                       std::string actualPath;
+                       bool found = PathSearcher::getGlobalSearcher().search(keyPath, PathSearcher::kFindFile, true, actualPath);
+                       if (!found)
+                       {
+                               throw std::runtime_error(format_string("unable to find key file %s\n", keyPath.c_str()));
+                       }
+                       
+                       std::ifstream keyStream(actualPath.c_str(), std::ios_base::in);
+                       if (!keyStream.is_open())
+                       {
+                               throw std::runtime_error(format_string("unable to read key file %s\n", keyPath.c_str()));
+                       }
+                       keyStream.seekg(0);
+                       
+                       try
+                       {
+                               // read as many keys as possible from the stream
+                               while (true)
+                               {
+                                       AESKey<128> key(keyStream);
+                                       encoreImage->addKey(key);
+                                       
+                                       // dump key bytes
+                                       dumpKey(key);
+                               }
+                       }
+                       catch (...)
+                       {
+                               // ignore the exception -- there are just no more keys in the stream
+                       }
+               }
+               
+               // add the default key of all zero bytes if requested
+               if (m_useDefaultKey)
+               {
+                       AESKey<128> defaultKey;
+                       encoreImage->addKey(defaultKey);
+               }
+       }
+       
+       /*!
+        * \brief Write the value of each byte of the \a key to the log.
+        */
+       void dumpKey(const AESKey<128> & key)
+       {
+               // dump key bytes
+               Log::log(Logger::DEBUG, "key bytes: ");
+               AESKey<128>::key_t the_key;
+               key.getKey(&the_key);
+               int q;
+               for (q=0; q<16; q++)
+               {
+                       Log::log(Logger::DEBUG, "%02x ", the_key[q]);
+               }
+               Log::log(Logger::DEBUG, "\n");
+       }
+
+};
+
+const elftosbTool::FamilyNameTableEntry elftosbTool::kFamilyNameTable[] =
+       {
+               { "37xx", k37xxFamily },
+               { "377x", k37xxFamily },
+               { "378x", k37xxFamily },
+               { "mx23", k37xxFamily },
+               { "imx23", k37xxFamily },
+               { "i.mx23", k37xxFamily },
+               { "mx28", kMX28Family },
+               { "imx28", kMX28Family },
+               { "i.mx28", kMX28Family },
+               
+               // Null terminator entry.
+               { NULL, k37xxFamily }
+       };
+
+/*!
+ * Main application entry point. Creates an sbtool instance and lets it take over.
+ */
+int main(int argc, char* argv[], char* envp[])
+{
+       try
+       {
+               return elftosbTool(argc, argv).run();
+       }
+       catch (...)
+       {
+               Log::log(Logger::ERROR, "error: unexpected exception\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+
+
diff --git a/tools/elftosb/elftosb2/elftosb2.vcproj b/tools/elftosb/elftosb2/elftosb2.vcproj
new file mode 100644 (file)
index 0000000..4de5589
--- /dev/null
@@ -0,0 +1,585 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9.00"\r
+       Name="elftosb2"\r
+       ProjectGUID="{ACBF9A30-8865-4DAA-B686-D8DC823CBF5C}"\r
+       RootNamespace="elftosb2"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories=".;..\winsupport;..\common"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               ForceConformanceInForLoopScope="true"\r
+                               RuntimeTypeInfo="true"\r
+                               UsePrecompiledHeader="0"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="2"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                               DisableSpecificWarnings="4355"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/elftosb.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/elftosb.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
+                               RuntimeLibrary="0"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/elftosb2.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <Filter\r
+                               Name="common"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\common\AESKey.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Blob.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\crc.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataSource.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataSourceImager.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataTarget.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELFSourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EncoreBootImage.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EvalContext.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ExcludesListMatcher.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\format_string.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GHSSecInfo.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GlobMatcher.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\HexValues.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\IVTDataSource.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Logging.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Operation.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionDictionary.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\options.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OutputSection.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Random.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\rijndael.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\RijndaelCBCMAC.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SearchPath.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SHA1.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SRecordSourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\stdafx.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StELFFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StExecutableImage.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StSRecordFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Value.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Version.cpp"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="elftosb"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\BootImageGenerator.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\ConversionController.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\elftosb.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\elftosb_lexer.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\elftosb_parser.tab.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\ElftosbAST.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\ElftosbLexer.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\EncoreBootImageGenerator.cpp"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+                       <Filter\r
+                               Name="common"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\common\AESKey.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Blob.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\BootImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\crc.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataSource.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataSourceImager.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataTarget.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELF.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELFSourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EncoreBootImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EndianUtilities.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EvalContext.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ExcludesListMatcher.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\format_string.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GHSSecInfo.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GlobMatcher.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\HexValues.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\int_size.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\IVTDataSource.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Logging.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Operation.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionContext.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionDictionary.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\options.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OutputSection.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Random.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\rijndael.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\RijndaelCBCMAC.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SearchPath.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SHA1.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\smart_ptr.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SRecordSourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\stdafx.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StELFFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StExecutableImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StringMatcher.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StSRecordFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Value.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Version.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="elftosb"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\BootImageGenerator.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\ConversionController.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\crypto.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\default_rom_key.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\elftosb.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\elftosb_parser.tab.hpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\ElftosbAST.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\ElftosbErrors.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\ElftosbLexer.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\EncoreBootImageGenerator.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\FlexLexer.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/tools/elftosb/elftosb2/elftosb_lexer.cpp b/tools/elftosb/elftosb2/elftosb_lexer.cpp
new file mode 100644 (file)
index 0000000..3b87842
--- /dev/null
@@ -0,0 +1,2241 @@
+#line 2 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_lexer.cpp"
+
+#line 4 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_lexer.cpp"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+    /* The c++ scanner is a mess. The FlexLexer.h header file relies on the
+     * following macro. This is required in order to pass the c++-multiple-scanners
+     * test in the regression suite. We get reports that it breaks inheritance.
+     * We will address this in a future release of flex, or omit the C++ scanner
+     * altogether.
+     */
+    #define yyFlexLexer yyFlexLexer
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+/* begin standard C++ headers. */
+#include <iostream> 
+#include <errno.h>
+#include <cstdlib>
+#include <cstring>
+/* end standard C++ headers. */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else  /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart( yyin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t yyleng;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                int yyl;\
+                for ( yyl = n; yyl < yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               *yy_cp = (yy_hold_char); \
+               YY_RESTORE_YY_MORE_OFFSET \
+               (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+               YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+               } \
+       while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+       {
+
+       std::istream* yy_input_file;
+
+       char *yy_ch_buf;                /* input buffer */
+       char *yy_buf_pos;               /* current position in input buffer */
+
+       /* Size of input buffer in bytes, not including room for EOB
+        * characters.
+        */
+       yy_size_t yy_buf_size;
+
+       /* Number of characters read into yy_ch_buf, not including EOB
+        * characters.
+        */
+       yy_size_t yy_n_chars;
+
+       /* Whether we "own" the buffer - i.e., we know we created it,
+        * and can realloc() it to grow it, and should free() it to
+        * delete it.
+        */
+       int yy_is_our_buffer;
+
+       /* Whether this is an "interactive" input source; if so, and
+        * if we're using stdio for input, then we want to use getc()
+        * instead of fread(), to make sure we stop fetching input after
+        * each newline.
+        */
+       int yy_is_interactive;
+
+       /* Whether we're considered to be at the beginning of a line.
+        * If so, '^' rules will be active on the next match, otherwise
+        * not.
+        */
+       int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+       /* Whether to try to fill the input buffer when we reach the
+        * end of it.
+        */
+       int yy_fill_buffer;
+
+       int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+       /* When an EOF's been seen but there's still some text to process
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+        * shouldn't try reading from the input source any more.  We might
+        * still have a bunch of tokens to match, though, because of
+        * possible backing-up.
+        *
+        * When we actually see the EOF, we change the status to "new"
+        * (via yyrestart()), so that the user can continue scanning by
+        * just pointing yyin at a new input file.
+        */
+#define YY_BUFFER_EOF_PENDING 2
+
+       };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+void *yyalloc (yy_size_t  );
+void *yyrealloc (void *,yy_size_t  );
+void yyfree (void *  );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+       }
+
+#define yy_set_bol(at_bol) \
+       { \
+       if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (); \
+               YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer( yyin, YY_BUF_SIZE ); \
+       } \
+       YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+       }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+#define yytext_ptr yytext
+
+#include <FlexLexer.h>
+
+int yyFlexLexer::yywrap() { return 1; }
+int yyFlexLexer::yylex()
+       {
+       LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" );
+       return 0;
+       }
+
+#define YY_DECL int ElftosbLexer::yylex()
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+       (yytext_ptr) = yy_bp; \
+       yyleng = (size_t) (yy_cp - yy_bp); \
+       (yy_hold_char) = *yy_cp; \
+       *yy_cp = '\0'; \
+       (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 74
+#define YY_END_OF_BUFFER 75
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+       {
+       flex_int32_t yy_verify;
+       flex_int32_t yy_nxt;
+       };
+static yyconst flex_int16_t yy_accept[218] =
+    {   0,
+        0,    0,    0,    0,    0,    0,   75,   73,   70,   71,
+       71,   64,   73,   73,   73,   49,   54,   73,   34,   35,
+       47,   45,   39,   46,   42,   48,   27,   27,   40,   41,
+       57,   38,   43,   26,   36,   37,   51,   26,   26,   26,
+       26,   26,   26,   26,   26,   26,   26,   26,   26,   26,
+       26,   26,   26,   26,   32,   55,   33,   50,   73,   73,
+       72,   70,   71,   72,   71,   61,    0,   65,    0,    0,
+       69,   29,   62,    0,    0,   56,   44,   30,    0,    0,
+       27,   27,    0,    0,   52,   59,   60,   58,   53,   26,
+       23,   26,   26,   26,   26,   26,   26,   26,   26,   26,
+
+       26,   26,   13,   26,   26,   26,   26,   26,   25,   26,
+       26,   26,   26,   26,   26,   26,   26,   31,   63,   66,
+       67,   68,    0,    0,   28,    0,    0,   27,   27,   26,
+       26,   20,   26,   26,   26,   26,   26,   26,   26,   21,
+       26,   22,   26,   26,   26,   26,    8,   26,   26,   26,
+       26,   26,   24,    0,    0,   28,    0,    0,    0,   11,
+       26,   26,   14,   26,   26,   26,   26,    7,   16,   10,
+        9,   12,   26,   26,   26,   26,   26,    0,    0,    0,
+        0,   28,    0,   26,   26,   18,   26,   26,   26,   26,
+       26,   26,   26,   28,    0,   28,    0,   26,   26,    6,
+
+       26,   26,   26,   19,   26,   26,    0,   26,   15,    4,
+        1,    5,    3,   17,   26,    2,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    5,    6,    7,    8,    9,   10,   11,   12,
+       13,   14,   15,   16,   17,   18,   19,   20,   21,   22,
+       22,   22,   22,   22,   22,   22,   22,   23,   24,   25,
+       26,   27,   28,    1,   29,   29,   30,   29,   31,   29,
+       32,   33,   33,   33,   32,   33,   32,   33,   33,   33,
+       33,   33,   34,   33,   33,   33,   33,   33,   33,   33,
+       35,    1,   36,   37,   33,    1,   38,   39,   40,   41,
+
+       42,   43,   44,   45,   46,   47,   33,   48,   49,   50,
+       51,   52,   33,   53,   54,   55,   56,   57,   58,   59,
+       60,   61,   62,   63,   64,   65,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[66] =
+    {   0,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    3,    1,    1,    3,    3,    1,    4,
+        4,    4,    1,    1,    1,    1,    1,    3,    4,    4,
+        4,    5,    5,    5,    3,    3,    3,    4,    4,    4,
+        4,    4,    4,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[231] =
+    {   0,
+        0,    0,   64,  127,   67,   73,  384,  385,  385,  385,
+      380,  356,   66,  378,    0,  385,  370,  348,  385,  385,
+      364,  385,  385,  385,  359,   59,   78,   94,  385,  385,
+       57,  350,   62,    0,  385,  385,  385,  191,   41,   69,
+       60,   74,  337,   75,  318,  322,  321,  320,  318,  331,
+       92,  315,  329,  324,  303,  301,  385,  385,    0,  299,
+      385,  385,  359,  342,  385,  385,  115,  385,  129,  357,
+      385,    0,  385,  111,  128,  385,  385,  385,  356,  121,
+      152,  385,   70,    0,  385,  385,  385,  385,  385,    0,
+      385,  310,  307,  315,  312,  300,  300,  297,  303,  302,
+
+      298,  309,    0,  304,  291,  296,  306,  302,    0,  287,
+      283,  300,  278,  282,  281,  283,  281,  385,  385,  385,
+      385,  385,  145,  113,  130,  200,  202,  218,  148,  286,
+      279,    0,  286,  289,  279,  287,  274,  272,  277,    0,
+      274,    0,  272,  282,  280,  275,    0,  265,  277,  265,
+      275,  266,    0,  146,  284,  283,  102,  148,  210,    0,
+      258,  262,    0,  258,  257,  267,  266,    0,    0,    0,
+        0,    0,  256,  257,  247,  253,  242,  270,  153,  160,
+      211,  212,  213,  214,  209,    0,  199,  195,  196,  189,
+      194,  194,  185,  385,  200,  198,  151,  162,  148,    0,
+
+      134,  132,  135,    0,  129,  111,  214,   90,    0,    0,
+        0,    0,    0,    0,   86,    0,  385,  256,  261,  266,
+      271,  274,  279,  281,   97,  286,   70,  291,  296,  301
+    } ;
+
+static yyconst flex_int16_t yy_def[231] =
+    {   0,
+      217,    1,  218,  218,  219,  219,  217,  217,  217,  217,
+      217,  217,  220,  221,  222,  217,  217,  223,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  224,  217,  217,  217,  224,  224,  224,
+      224,  224,   38,  224,  224,  224,  224,  224,  224,  224,
+      224,  224,   38,  224,  217,  217,  217,  217,  225,  217,
+      217,  217,  217,  217,  217,  217,  220,  217,  220,  221,
+      217,  222,  217,  226,  226,  217,  217,  217,  221,  217,
+      217,  217,  217,  227,  217,  217,  217,  217,  217,  224,
+      217,  224,  224,  224,  224,  224,  224,  224,  224,  224,
+
+      224,  224,  224,  224,  224,  224,  224,  224,  224,  224,
+      224,  224,  224,  224,  224,  224,  224,  217,  217,  217,
+      217,  217,  220,  228,  228,  228,  228,  217,  227,  224,
+      224,  224,  224,  224,  224,  224,  224,  224,  224,  224,
+      224,  224,  224,  224,  224,  224,  224,  224,  224,  224,
+      224,  224,  224,  220,  229,  229,  229,  229,  230,  224,
+      224,  224,  224,  224,  224,  224,  224,  224,  224,  224,
+      224,  224,  224,  224,  224,  224,  224,  217,  217,  217,
+      228,  228,  228,  224,  224,  224,  224,  224,  224,  224,
+      224,  224,  224,  217,  217,  229,  229,  224,  224,  224,
+
+      224,  224,  224,  224,  224,  224,  228,  224,  224,  224,
+      224,  224,  224,  224,  224,  224,    0,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217
+    } ;
+
+static yyconst flex_int16_t yy_nxt[451] =
+    {   0,
+        8,    9,   10,   11,   12,   13,   14,   15,   16,   17,
+       18,   19,   20,   21,   22,   23,   24,   25,   26,   27,
+       28,   28,   29,   30,   31,   32,   33,    8,   34,   34,
+       34,   34,   34,   34,   35,   36,   37,   34,   38,   39,
+       40,   41,   42,   34,   43,   44,   45,   46,   47,   48,
+       49,   34,   50,   51,   52,   34,   34,   53,   34,   54,
+       34,   55,   56,   57,   58,    9,   10,   11,   62,   10,
+       63,   68,   78,  129,   62,   10,   63,   79,   92,   80,
+       64,   85,   86,   59,   59,   59,   64,   88,   89,  128,
+      128,   93,   59,   59,   59,   80,   69,   81,   81,   81,
+
+      120,   59,   59,   59,   59,   59,   59,   96,   94,   82,
+       95,   99,   97,   81,   81,   81,   83,  103,   98,  100,
+       68,  125,   80,  156,  104,   82,  101,   60,    9,   10,
+       11,  105,  179,  112,   68,  180,   84,  113,  125,  216,
+      156,  126,  114,  157,  215,   69,   59,   59,   59,   80,
+       68,   68,   82,   80,  214,   59,   59,   59,  126,   69,
+      157,  127,  123,  194,   59,   59,   59,   59,   59,   59,
+      194,   81,   81,   81,  154,   69,   69,  181,  179,   82,
+      207,  179,  213,   82,  212,  211,  195,  210,  209,  155,
+       60,   91,   91,   91,   91,   91,   91,   91,   91,   91,
+
+       91,   91,   91,   91,   91,   91,   91,   91,   91,   91,
+      156,  208,  156,   91,   91,   91,   91,   91,   91,   80,
+      182,  196,  196,  196,  196,   91,   91,   91,  179,  178,
+      157,  159,  157,  158,  206,  205,  204,  128,  128,  203,
+      183,  157,  157,  157,  157,  202,  197,  201,  200,   82,
+      199,  198,   91,   91,   91,   91,    8,    8,    8,    8,
+        8,   61,   61,   61,   61,   61,   67,   67,   67,   67,
+       67,   70,   70,   70,   70,   70,   72,   72,   72,   74,
+      194,   74,   74,   74,   90,   90,  124,  193,  124,  124,
+      124,  155,  192,  155,  155,  155,  178,  191,  178,  178,
+
+      178,  181,  190,  181,  181,  181,  189,  188,  109,  187,
+      186,  185,  184,  179,  179,  177,  153,  176,  175,  174,
+      173,  172,  171,  170,  169,  168,  167,  166,  165,  164,
+      163,  162,  161,  160,  153,  152,  151,  150,  149,  148,
+      147,  146,  145,  144,  143,  142,  141,  140,  139,  138,
+      137,  136,  135,  134,  133,  132,  131,  130,   71,   71,
+      122,   65,  121,  119,  118,  117,  116,  115,  111,  110,
+      109,  108,  107,  106,  102,   87,   77,   76,   75,   73,
+       71,   66,   65,  217,    7,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217
+    } ;
+
+static yyconst flex_int16_t yy_chk[451] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    3,    3,    3,    5,    5,
+        5,   13,   26,  227,    6,    6,    6,   26,   39,   27,
+        5,   31,   31,    3,    3,    3,    6,   33,   33,   83,
+       83,   39,    3,    3,    3,   28,   13,   27,   27,   27,
+
+      225,    3,    3,    3,    3,    3,    3,   41,   40,   27,
+       40,   42,   41,   28,   28,   28,   27,   44,   41,   42,
+       67,   74,   80,  124,   44,   28,   42,    3,    4,    4,
+        4,   44,  157,   51,   69,  157,   27,   51,   75,  215,
+      125,   74,   51,  124,  208,   67,    4,    4,    4,  129,
+      123,  154,   80,   81,  206,    4,    4,    4,   75,   69,
+      125,   75,   69,  179,    4,    4,    4,    4,    4,    4,
+      180,   81,   81,   81,  123,  123,  154,  158,  158,  129,
+      197,  197,  205,   81,  203,  202,  179,  201,  199,  180,
+        4,   38,   38,   38,   38,   38,   38,   38,   38,   38,
+
+       38,   38,   38,   38,   38,   38,   38,   38,   38,   38,
+      126,  198,  127,   38,   38,   38,   38,   38,   38,  128,
+      159,  181,  182,  183,  207,   38,   38,   38,  196,  195,
+      126,  127,  127,  126,  193,  192,  191,  128,  128,  190,
+      159,  181,  182,  183,  207,  189,  183,  188,  187,  128,
+      185,  184,   38,   38,   38,   38,  218,  218,  218,  218,
+      218,  219,  219,  219,  219,  219,  220,  220,  220,  220,
+      220,  221,  221,  221,  221,  221,  222,  222,  222,  223,
+      178,  223,  223,  223,  224,  224,  226,  177,  226,  226,
+      226,  228,  176,  228,  228,  228,  229,  175,  229,  229,
+
+      229,  230,  174,  230,  230,  230,  173,  167,  166,  165,
+      164,  162,  161,  156,  155,  152,  151,  150,  149,  148,
+      146,  145,  144,  143,  141,  139,  138,  137,  136,  135,
+      134,  133,  131,  130,  117,  116,  115,  114,  113,  112,
+      111,  110,  108,  107,  106,  105,  104,  102,  101,  100,
+       99,   98,   97,   96,   95,   94,   93,   92,   79,   70,
+       64,   63,   60,   56,   55,   54,   53,   52,   50,   49,
+       48,   47,   46,   45,   43,   32,   25,   21,   18,   17,
+       14,   12,   11,    7,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217,
+      217,  217,  217,  217,  217,  217,  217,  217,  217,  217
+    } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[75] =
+    {   0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0,     };
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+/* %option prefix="Elftosb" */
+#line 10 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+#include "ElftosbLexer.h"
+#include <stdlib.h>
+#include <limits.h>
+#include <string>
+#include "HexValues.h"
+#include "Value.h"
+
+using namespace elftosb;
+
+//! Always executed before all other actions when a token is matched.
+//! This action just assign the first and last lines of the token to
+//! the current line. In most cases this is correct.
+#define YY_USER_ACTION do {                                                                    \
+                                                       m_location.m_firstLine = m_line;                \
+                                                       m_location.m_lastLine = m_line;         \
+                                               } while (0);
+
+/* start conditions */
+
+#line 628 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_lexer.cpp"
+
+#define INITIAL 0
+#define blob 1
+#define mlcmt 2
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+#define ECHO LexerOutput( yytext, yyleng )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+\
+       if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \
+               YY_FATAL_ERROR( "input in flex scanner failed" );
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) LexerError( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+#define YY_DECL int yyFlexLexer::yylex()
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+       YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp, *yy_bp;
+       register int yy_act;
+    
+#line 38 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+
+
+#line 733 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_lexer.cpp"
+
+       if ( !(yy_init) )
+               {
+               (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+               YY_USER_INIT;
+#endif
+
+               if ( ! (yy_start) )
+                       (yy_start) = 1; /* first start state */
+
+               if ( ! yyin )
+                       yyin = & std::cin;
+
+               if ( ! yyout )
+                       yyout = & std::cout;
+
+               if ( ! YY_CURRENT_BUFFER ) {
+                       yyensure_buffer_stack ();
+                       YY_CURRENT_BUFFER_LVALUE =
+                               yy_create_buffer( yyin, YY_BUF_SIZE );
+               }
+
+               yy_load_buffer_state(  );
+               }
+
+       while ( 1 )             /* loops until end-of-file is reached */
+               {
+               yy_cp = (yy_c_buf_p);
+
+               /* Support of yytext. */
+               *yy_cp = (yy_hold_char);
+
+               /* yy_bp points to the position in yy_ch_buf of the start of
+                * the current run.
+                */
+               yy_bp = yy_cp;
+
+               yy_current_state = (yy_start);
+yy_match:
+               do
+                       {
+                       register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+                       if ( yy_accept[yy_current_state] )
+                               {
+                               (yy_last_accepting_state) = yy_current_state;
+                               (yy_last_accepting_cpos) = yy_cp;
+                               }
+                       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                               {
+                               yy_current_state = (int) yy_def[yy_current_state];
+                               if ( yy_current_state >= 218 )
+                                       yy_c = yy_meta[(unsigned int) yy_c];
+                               }
+                       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+                       ++yy_cp;
+                       }
+               while ( yy_current_state != 217 );
+               yy_cp = (yy_last_accepting_cpos);
+               yy_current_state = (yy_last_accepting_state);
+
+yy_find_action:
+               yy_act = yy_accept[yy_current_state];
+
+               YY_DO_BEFORE_ACTION;
+
+               if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+                       {
+                       int yyl;
+                       for ( yyl = 0; yyl < yyleng; ++yyl )
+                               if ( yytext[yyl] == '\n' )
+                                          
+    yylineno++;
+;
+                       }
+
+do_action:     /* This label is used only to access EOF actions. */
+
+               switch ( yy_act )
+       { /* beginning of action switch */
+                       case 0: /* must back up */
+                       /* undo the effects of YY_DO_BEFORE_ACTION */
+                       *yy_cp = (yy_hold_char);
+                       yy_cp = (yy_last_accepting_cpos);
+                       yy_current_state = (yy_last_accepting_state);
+                       goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 40 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_OPTIONS; }
+       YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 41 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_CONSTANTS; }
+       YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 42 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_SOURCES; }
+       YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 43 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_FILTERS; }
+       YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 44 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_SECTION; }
+       YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 45 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_EXTERN; }
+       YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 46 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_FROM; }
+       YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 47 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_RAW; }
+       YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 48 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_LOAD; }
+       YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 49 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_JUMP; }
+       YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 50 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_CALL; }
+       YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 51 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_MODE; }
+       YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 52 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_IF; }
+       YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 53 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_ELSE; }
+       YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 54 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_DEFINED; }
+       YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 55 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_INFO; }
+       YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 56 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_WARNING; }
+       YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 57 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_ERROR; }
+       YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 58 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_SIZEOF; }
+       YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 59 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_DCD; }
+       YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 60 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_HAB; }
+       YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 61 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_IVT; }
+       YY_BREAK
+case 23:
+/* rule 23 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+(yy_c_buf_p) = yy_cp = yy_bp + 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 63 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{      // must be followed by any non-ident char
+                                                                               int_size_t theSize;
+                                                                               switch (yytext[0])
+                                                                               {
+                                                                                       case 'w':
+                                                                                               theSize = kWordSize;
+                                                                                               break;
+                                                                                       case 'h':
+                                                                                               theSize = kHalfWordSize;
+                                                                                               break;
+                                                                                       case 'b':
+                                                                                               theSize = kByteSize;
+                                                                                               break;
+                                                                               }
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(0, theSize);
+                                                                               return TOK_INT_SIZE;
+                                                                       }
+       YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 81 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(1, kWordSize);
+                                                                               return TOK_INT_LITERAL;
+                                                                       }
+       YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 86 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(0, kWordSize);
+                                                                               return TOK_INT_LITERAL;
+                                                                       }
+       YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 91 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               m_symbolValue.m_str = new std::string(yytext);
+                                                                               if (isSourceName(m_symbolValue.m_str))
+                                                                               {
+                                                                                       return TOK_SOURCE_NAME;
+                                                                               }
+                                                                               else
+                                                                               {
+                                                                                       return TOK_IDENT;
+                                                                               }
+                                                                       }
+       YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 103 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               int base = 0;
+                                                                               uint32_t value;
+                                                                               int mult;
+                                                                               
+                                                                               // check for binary number
+                                                                               if (yytext[0] == '0' && yytext[1] == 'b')
+                                                                               {
+                                                                                       base = 2;               // this is a binary number
+                                                                                       yytext += 2;    // skip over the "0b"
+                                                                               }
+                                                                               
+                                                                               // convert value
+                                                                               value = (uint32_t)strtoul(yytext, NULL, base);
+                                                                               
+                                                                               // find multiplier
+                                                                               switch (yytext[strlen(yytext) - 1])
+                                                                               {
+                                                                                       case 'G':
+                                                                                               mult = 1024 * 1024 * 1024;
+                                                                                               break;
+                                                                                       case 'M':
+                                                                                               mult = 1024 * 1024;
+                                                                                               break;
+                                                                                       case 'K':
+                                                                                               mult = 1024;
+                                                                                               break;
+                                                                                       default:
+                                                                                               mult = 1;
+                                                                                               break;
+                                                                               }
+                                                                               
+                                                                               // set resulting symbol value
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(value * mult, kWordSize);
+                                                                               return TOK_INT_LITERAL;
+                                                                       }
+       YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 140 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               uint32_t value = 0;
+                                                                               int_size_t theSize;
+                                                                               int len = strlen(yytext);
+                                                                               if (len >= 3)
+                                                                               {
+                                                                                       value = yytext[1];
+                                                                                       theSize = kByteSize;
+                                                                               }
+                                                                               if (len >= 4)
+                                                                               {
+                                                                                       value = (value << 8) | yytext[2];
+                                                                                       theSize = kHalfWordSize;
+                                                                               }
+                                                                               if (len >= 6)
+                                                                               {
+                                                                                       value = (value << 8) | yytext[3];
+                                                                                       value = (value << 8) | yytext[4];
+                                                                                       theSize = kWordSize;
+                                                                               }
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(value, theSize);
+                                                                               return TOK_INT_LITERAL;
+                                                                       }
+       YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 164 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               // remove $ from string
+                                                                               m_symbolValue.m_str = new std::string(&yytext[1]);
+                                                                               return TOK_SECTION_NAME;
+                                                                       }
+       YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 171 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ BEGIN(mlcmt); }
+       YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 173 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               m_blob = new Blob();
+                                                                               m_blobFirstLine = yylineno;
+                                                                               BEGIN(blob);
+                                                                       }
+       YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 179 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '{'; }
+       YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 181 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '}'; }
+       YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 183 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '('; }
+       YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 185 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return ')'; }
+       YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 187 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '['; }
+       YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 189 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return ']'; }
+       YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 191 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '='; }
+       YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 193 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return ','; }
+       YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 195 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return ':'; }
+       YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 197 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return ';'; }
+       YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 199 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '.'; }
+       YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 201 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '>'; }
+       YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 203 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_DOT_DOT; }
+       YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 205 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '+'; }
+       YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 207 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '-'; }
+       YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 209 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '*'; }
+       YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 211 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '/'; }
+       YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 213 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '%'; }
+       YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 215 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '~'; }
+       YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 217 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '^'; }
+       YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 219 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_LSHIFT; }
+       YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 221 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_RSHIFT; }
+       YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 223 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '&'; }
+       YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 225 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '|'; }
+       YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 227 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_POWER; }
+       YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 229 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '<'; }
+       YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 231 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_GEQ; }
+       YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 233 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_LEQ; }
+       YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 235 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_EQ; }
+       YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 237 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_NEQ; }
+       YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 239 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_AND; }
+       YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 241 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return TOK_OR; }
+       YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 243 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{ return '!'; }
+       YY_BREAK
+case 65:
+/* rule 65 can match eol */
+YY_RULE_SETUP
+#line 245 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               // get rid of quotes
+                                                                               yytext++;
+                                                                               yytext[strlen(yytext) - 1] = 0;
+//                                                                             processStringEscapes(yytext, yytext);
+                                                                               m_symbolValue.m_str = new std::string(yytext);
+                                                                               return TOK_STRING_LITERAL;
+                                                                       }
+       YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 254 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               uint8_t x = (hexCharToInt(yytext[0]) << 4) | hexCharToInt(yytext[1]);
+                                                                               m_blob->append(&x, 1);
+                                                                       }
+       YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 259 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               BEGIN(INITIAL);
+                                                                               m_symbolValue.m_blob = m_blob;
+                                                                               m_blob = NULL;
+                                                                               m_location.m_firstLine = m_blobFirstLine;
+                                                                               return TOK_BLOB;
+                                                                       }
+       YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 267 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                        // end of multi-line comment, return to initial state
+                                        BEGIN(INITIAL);
+                                    }
+       YY_BREAK
+case 69:
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 273 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+/* absorb single-line comment */
+       YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 275 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+/* eat up whitespace in all states */
+       YY_BREAK
+case 71:
+/* rule 71 can match eol */
+YY_RULE_SETUP
+#line 277 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               /* eat up whitespace and count lines in all states */
+                                                                               m_line++;
+                                                                       }
+       YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 282 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+/* ignore all other chars in a multi-line comment */
+       YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 284 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+{
+                                                                               /* all other chars produce errors */
+                                                                               char msg[50];
+                                                                               sprintf(msg, "unexpected character '%c' on line %d", yytext[0], m_line);
+                                                                               LexerError(msg);
+                                                                       }
+       YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 291 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+ECHO;
+       YY_BREAK
+#line 1325 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_lexer.cpp"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(blob):
+case YY_STATE_EOF(mlcmt):
+       yyterminate();
+
+       case YY_END_OF_BUFFER:
+               {
+               /* Amount of text matched not including the EOB char. */
+               int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+               /* Undo the effects of YY_DO_BEFORE_ACTION. */
+               *yy_cp = (yy_hold_char);
+               YY_RESTORE_YY_MORE_OFFSET
+
+               if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+                       {
+                       /* We're scanning a new file or input source.  It's
+                        * possible that this happened because the user
+                        * just pointed yyin at a new source and called
+                        * yylex().  If so, then we have to assure
+                        * consistency between YY_CURRENT_BUFFER and our
+                        * globals.  Here is the right place to do so, because
+                        * this is the first action (other than possibly a
+                        * back-up) that will match for the new input source.
+                        */
+                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+                       YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+                       }
+
+               /* Note that here we test for yy_c_buf_p "<=" to the position
+                * of the first EOB in the buffer, since yy_c_buf_p will
+                * already have been incremented past the NUL character
+                * (since all states make transitions on EOB to the
+                * end-of-buffer state).  Contrast this with the test
+                * in input().
+                */
+               if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+                       { /* This was really a NUL. */
+                       yy_state_type yy_next_state;
+
+                       (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+                       yy_current_state = yy_get_previous_state(  );
+
+                       /* Okay, we're now positioned to make the NUL
+                        * transition.  We couldn't have
+                        * yy_get_previous_state() go ahead and do it
+                        * for us because it doesn't know how to deal
+                        * with the possibility of jamming (and we don't
+                        * want to build jamming into it because then it
+                        * will run more slowly).
+                        */
+
+                       yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+                       yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+                       if ( yy_next_state )
+                               {
+                               /* Consume the NUL. */
+                               yy_cp = ++(yy_c_buf_p);
+                               yy_current_state = yy_next_state;
+                               goto yy_match;
+                               }
+
+                       else
+                               {
+                               yy_cp = (yy_last_accepting_cpos);
+                               yy_current_state = (yy_last_accepting_state);
+                               goto yy_find_action;
+                               }
+                       }
+
+               else switch ( yy_get_next_buffer(  ) )
+                       {
+                       case EOB_ACT_END_OF_FILE:
+                               {
+                               (yy_did_buffer_switch_on_eof) = 0;
+
+                               if ( yywrap(  ) )
+                                       {
+                                       /* Note: because we've taken care in
+                                        * yy_get_next_buffer() to have set up
+                                        * yytext, we can now set up
+                                        * yy_c_buf_p so that if some total
+                                        * hoser (like flex itself) wants to
+                                        * call the scanner after we return the
+                                        * YY_NULL, it'll still work - another
+                                        * YY_NULL will get returned.
+                                        */
+                                       (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+                                       yy_act = YY_STATE_EOF(YY_START);
+                                       goto do_action;
+                                       }
+
+                               else
+                                       {
+                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                               YY_NEW_FILE;
+                                       }
+                               break;
+                               }
+
+                       case EOB_ACT_CONTINUE_SCAN:
+                               (yy_c_buf_p) =
+                                       (yytext_ptr) + yy_amount_of_matched_text;
+
+                               yy_current_state = yy_get_previous_state(  );
+
+                               yy_cp = (yy_c_buf_p);
+                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               goto yy_match;
+
+                       case EOB_ACT_LAST_MATCH:
+                               (yy_c_buf_p) =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+                               yy_current_state = yy_get_previous_state(  );
+
+                               yy_cp = (yy_c_buf_p);
+                               yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+                               goto yy_find_action;
+                       }
+               break;
+               }
+
+       default:
+               YY_FATAL_ERROR(
+                       "fatal flex scanner internal error--no action found" );
+       } /* end of action switch */
+               } /* end of scanning one token */
+} /* end of yylex */
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout )
+{
+       yyin = arg_yyin;
+       yyout = arg_yyout;
+       yy_c_buf_p = 0;
+       yy_init = 0;
+       yy_start = 0;
+       yy_flex_debug = 0;
+       yylineno = 1;   // this will only get updated if %option yylineno
+
+       yy_did_buffer_switch_on_eof = 0;
+
+       yy_looking_for_trail_begin = 0;
+       yy_more_flag = 0;
+       yy_more_len = 0;
+       yy_more_offset = yy_prev_more_offset = 0;
+
+       yy_start_stack_ptr = yy_start_stack_depth = 0;
+       yy_start_stack = NULL;
+
+       yy_buffer_stack = 0;
+       yy_buffer_stack_top = 0;
+       yy_buffer_stack_max = 0;
+
+       yy_state_buf = 0;
+
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+yyFlexLexer::~yyFlexLexer()
+{
+       delete [] yy_state_buf;
+       yyfree(yy_start_stack  );
+       yy_delete_buffer( YY_CURRENT_BUFFER );
+       yyfree(yy_buffer_stack  );
+}
+
+/* The contents of this function are C++ specific, so the () macro is not used.
+ */
+void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out )
+{
+       if ( new_in )
+               {
+               yy_delete_buffer( YY_CURRENT_BUFFER );
+               yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE  ) );
+               }
+
+       if ( new_out )
+               yyout = new_out;
+}
+
+#ifdef YY_INTERACTIVE
+int yyFlexLexer::LexerInput( char* buf, int /* max_size */ )
+#else
+int yyFlexLexer::LexerInput( char* buf, int max_size )
+#endif
+{
+       if ( yyin->eof() || yyin->fail() )
+               return 0;
+
+#ifdef YY_INTERACTIVE
+       yyin->get( buf[0] );
+
+       if ( yyin->eof() )
+               return 0;
+
+       if ( yyin->bad() )
+               return -1;
+
+       return 1;
+
+#else
+       (void) yyin->read( buf, max_size );
+
+       if ( yyin->bad() )
+               return -1;
+       else
+               return yyin->gcount();
+#endif
+}
+
+void yyFlexLexer::LexerOutput( const char* buf, int size )
+{
+       (void) yyout->write( buf, size );
+}
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *     EOB_ACT_LAST_MATCH -
+ *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *     EOB_ACT_END_OF_FILE - end of file
+ */
+int yyFlexLexer::yy_get_next_buffer()
+{
+       register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+       register char *source = (yytext_ptr);
+       register int number_to_move, i;
+       int ret_val;
+
+       if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+               YY_FATAL_ERROR(
+               "fatal flex scanner internal error--end of buffer missed" );
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+               { /* Don't try to fill the buffer, so this is an EOF. */
+               if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+                       {
+                       /* We matched a single character, the EOB, so
+                        * treat this as a final EOF.
+                        */
+                       return EOB_ACT_END_OF_FILE;
+                       }
+
+               else
+                       {
+                       /* We matched some text prior to the EOB, first
+                        * process it.
+                        */
+                       return EOB_ACT_LAST_MATCH;
+                       }
+               }
+
+       /* Try to read more data. */
+
+       /* First move last chars to start of buffer. */
+       number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+       for ( i = 0; i < number_to_move; ++i )
+               *(dest++) = *(source++);
+
+       if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+               /* don't do the read, it's not guaranteed to return an EOF,
+                * just force an EOF
+                */
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+       else
+               {
+                       yy_size_t num_to_read =
+                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+               while ( num_to_read <= 0 )
+                       { /* Not enough room in the buffer - grow it. */
+
+                       /* just a shorter name for the current buffer */
+                       YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+                       int yy_c_buf_p_offset =
+                               (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+                       if ( b->yy_is_our_buffer )
+                               {
+                               yy_size_t new_size = b->yy_buf_size * 2;
+
+                               if ( new_size <= 0 )
+                                       b->yy_buf_size += b->yy_buf_size / 8;
+                               else
+                                       b->yy_buf_size *= 2;
+
+                               b->yy_ch_buf = (char *)
+                                       /* Include room in for 2 EOB chars. */
+                                       yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+                               }
+                       else
+                               /* Can't grow it, we don't own it. */
+                               b->yy_ch_buf = 0;
+
+                       if ( ! b->yy_ch_buf )
+                               YY_FATAL_ERROR(
+                               "fatal error - scanner input buffer overflow" );
+
+                       (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+                       num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+                                               number_to_move - 1;
+
+                       }
+
+               if ( num_to_read > YY_READ_BUF_SIZE )
+                       num_to_read = YY_READ_BUF_SIZE;
+
+               /* Read in more data. */
+               YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+                       (yy_n_chars), num_to_read );
+
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       if ( (yy_n_chars) == 0 )
+               {
+               if ( number_to_move == YY_MORE_ADJ )
+                       {
+                       ret_val = EOB_ACT_END_OF_FILE;
+                       yyrestart( yyin  );
+                       }
+
+               else
+                       {
+                       ret_val = EOB_ACT_LAST_MATCH;
+                       YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+                               YY_BUFFER_EOF_PENDING;
+                       }
+               }
+
+       else
+               ret_val = EOB_ACT_CONTINUE_SCAN;
+
+       if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+               /* Extend the array by 50%, plus the number we really need. */
+               yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+               YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size  );
+               if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+       }
+
+       (yy_n_chars) += number_to_move;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+       YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+       (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+       return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    yy_state_type yyFlexLexer::yy_get_previous_state()
+{
+       register yy_state_type yy_current_state;
+       register char *yy_cp;
+    
+       yy_current_state = (yy_start);
+
+       for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+               {
+               register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+               if ( yy_accept[yy_current_state] )
+                       {
+                       (yy_last_accepting_state) = yy_current_state;
+                       (yy_last_accepting_cpos) = yy_cp;
+                       }
+               while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+                       {
+                       yy_current_state = (int) yy_def[yy_current_state];
+                       if ( yy_current_state >= 218 )
+                               yy_c = yy_meta[(unsigned int) yy_c];
+                       }
+               yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+               }
+
+       return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *     next_state = yy_try_NUL_trans( current_state );
+ */
+    yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state )
+{
+       register int yy_is_jam;
+       register char *yy_cp = (yy_c_buf_p);
+
+       register YY_CHAR yy_c = 1;
+       if ( yy_accept[yy_current_state] )
+               {
+               (yy_last_accepting_state) = yy_current_state;
+               (yy_last_accepting_cpos) = yy_cp;
+               }
+       while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+               {
+               yy_current_state = (int) yy_def[yy_current_state];
+               if ( yy_current_state >= 218 )
+                       yy_c = yy_meta[(unsigned int) yy_c];
+               }
+       yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+       yy_is_jam = (yy_current_state == 217);
+
+       return yy_is_jam ? 0 : yy_current_state;
+}
+
+    void yyFlexLexer::yyunput( int c, register char* yy_bp)
+{
+       register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+       /* undo effects of setting up yytext */
+       *yy_cp = (yy_hold_char);
+
+       if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+               { /* need to shift things up to make room */
+               /* +2 for EOB chars. */
+               register yy_size_t number_to_move = (yy_n_chars) + 2;
+               register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+                                       YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+               register char *source =
+                               &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+               while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+                       *--dest = *--source;
+
+               yy_cp += (int) (dest - source);
+               yy_bp += (int) (dest - source);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+                       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+               if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+                       YY_FATAL_ERROR( "flex scanner push-back overflow" );
+               }
+
+       *--yy_cp = (char) c;
+
+    if ( c == '\n' ){
+        --yylineno;
+    }
+
+       (yytext_ptr) = yy_bp;
+       (yy_hold_char) = *yy_cp;
+       (yy_c_buf_p) = yy_cp;
+}
+
+    int yyFlexLexer::yyinput()
+{
+       int c;
+    
+       *(yy_c_buf_p) = (yy_hold_char);
+
+       if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+               {
+               /* yy_c_buf_p now points to the character we want to return.
+                * If this occurs *before* the EOB characters, then it's a
+                * valid NUL; if not, then we've hit the end of the buffer.
+                */
+               if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+                       /* This was really a NUL. */
+                       *(yy_c_buf_p) = '\0';
+
+               else
+                       { /* need more input */
+                       yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+                       ++(yy_c_buf_p);
+
+                       switch ( yy_get_next_buffer(  ) )
+                               {
+                               case EOB_ACT_LAST_MATCH:
+                                       /* This happens because yy_g_n_b()
+                                        * sees that we've accumulated a
+                                        * token and flags that we need to
+                                        * try matching the token before
+                                        * proceeding.  But for input(),
+                                        * there's no matching to consider.
+                                        * So convert the EOB_ACT_LAST_MATCH
+                                        * to EOB_ACT_END_OF_FILE.
+                                        */
+
+                                       /* Reset buffer status. */
+                                       yyrestart( yyin );
+
+                                       /*FALLTHROUGH*/
+
+                               case EOB_ACT_END_OF_FILE:
+                                       {
+                                       if ( yywrap(  ) )
+                                               return 0;
+
+                                       if ( ! (yy_did_buffer_switch_on_eof) )
+                                               YY_NEW_FILE;
+#ifdef __cplusplus
+                                       return yyinput();
+#else
+                                       return input();
+#endif
+                                       }
+
+                               case EOB_ACT_CONTINUE_SCAN:
+                                       (yy_c_buf_p) = (yytext_ptr) + offset;
+                                       break;
+                               }
+                       }
+               }
+
+       c = *(unsigned char *) (yy_c_buf_p);    /* cast for 8-bit char's */
+       *(yy_c_buf_p) = '\0';   /* preserve yytext */
+       (yy_hold_char) = *++(yy_c_buf_p);
+
+       if ( c == '\n' )
+                  
+    yylineno++;
+;
+
+       return c;
+}
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyFlexLexer::yyrestart( std::istream* input_file )
+{
+    
+       if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack ();
+               YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer( yyin, YY_BUF_SIZE );
+       }
+
+       yy_init_buffer( YY_CURRENT_BUFFER, input_file );
+       yy_load_buffer_state(  );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
+{
+    
+       /* TODO. We should be able to replace this entire function body
+        * with
+        *              yypop_buffer_state();
+        *              yypush_buffer_state(new_buffer);
+     */
+       yyensure_buffer_stack ();
+       if ( YY_CURRENT_BUFFER == new_buffer )
+               return;
+
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *(yy_c_buf_p) = (yy_hold_char);
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+       yy_load_buffer_state(  );
+
+       /* We don't actually know whether we did this switch during
+        * EOF (yywrap()) processing, but the only time this flag
+        * is looked at is after yywrap() is called, so it's safe
+        * to go ahead and always set it.
+        */
+       (yy_did_buffer_switch_on_eof) = 1;
+}
+
+    void yyFlexLexer::yy_load_buffer_state()
+{
+       (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+       (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+       yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+       (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size )
+{
+       YY_BUFFER_STATE b;
+    
+       b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state )  );
+       if ( ! b )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_buf_size = size;
+
+       /* yy_ch_buf has to be 2 characters longer than the size given because
+        * we need to put in 2 end-of-buffer characters.
+        */
+       b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2  );
+       if ( ! b->yy_ch_buf )
+               YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+       b->yy_is_our_buffer = 1;
+
+       yy_init_buffer( b, file );
+
+       return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * 
+ */
+    void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b )
+{
+    
+       if ( ! b )
+               return;
+
+       if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+               YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+       if ( b->yy_is_our_buffer )
+               yyfree((void *) b->yy_ch_buf  );
+
+       yyfree((void *) b  );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file )
+
+{
+       int oerrno = errno;
+    
+       yy_flush_buffer( b );
+
+       b->yy_input_file = file;
+       b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+       b->yy_is_interactive = 0;
+       errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b )
+{
+       if ( ! b )
+               return;
+
+       b->yy_n_chars = 0;
+
+       /* We always need two end-of-buffer characters.  The first causes
+        * a transition to the end-of-buffer state.  The second causes
+        * a jam in that state.
+        */
+       b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+       b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+       b->yy_buf_pos = &b->yy_ch_buf[0];
+
+       b->yy_at_bol = 1;
+       b->yy_buffer_status = YY_BUFFER_NEW;
+
+       if ( b == YY_CURRENT_BUFFER )
+               yy_load_buffer_state(  );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer)
+{
+       if (new_buffer == NULL)
+               return;
+
+       yyensure_buffer_stack();
+
+       /* This block is copied from yy_switch_to_buffer. */
+       if ( YY_CURRENT_BUFFER )
+               {
+               /* Flush out information for old buffer. */
+               *(yy_c_buf_p) = (yy_hold_char);
+               YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+               YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+               }
+
+       /* Only push if top exists. Otherwise, replace top. */
+       if (YY_CURRENT_BUFFER)
+               (yy_buffer_stack_top)++;
+       YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+       /* copied from yy_switch_to_buffer. */
+       yy_load_buffer_state(  );
+       (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void yyFlexLexer::yypop_buffer_state (void)
+{
+       if (!YY_CURRENT_BUFFER)
+               return;
+
+       yy_delete_buffer(YY_CURRENT_BUFFER );
+       YY_CURRENT_BUFFER_LVALUE = NULL;
+       if ((yy_buffer_stack_top) > 0)
+               --(yy_buffer_stack_top);
+
+       if (YY_CURRENT_BUFFER) {
+               yy_load_buffer_state(  );
+               (yy_did_buffer_switch_on_eof) = 1;
+       }
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+void yyFlexLexer::yyensure_buffer_stack(void)
+{
+       yy_size_t num_to_alloc;
+    
+       if (!(yy_buffer_stack)) {
+
+               /* First allocation is just for 2 elements, since we don't know if this
+                * scanner will even need a stack. We use 2 instead of 1 to avoid an
+                * immediate realloc on the next call.
+         */
+               num_to_alloc = 1;
+               (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+                                                               (num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+                                                                 
+               memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+                               
+               (yy_buffer_stack_max) = num_to_alloc;
+               (yy_buffer_stack_top) = 0;
+               return;
+       }
+
+       if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+               /* Increase the buffer to prepare for a possible push. */
+               int grow_size = 8 /* arbitrary grow size */;
+
+               num_to_alloc = (yy_buffer_stack_max) + grow_size;
+               (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+                                                               ((yy_buffer_stack),
+                                                               num_to_alloc * sizeof(struct yy_buffer_state*)
+                                                               );
+               if ( ! (yy_buffer_stack) )
+                       YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+               /* zero only the new slots.*/
+               memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+               (yy_buffer_stack_max) = num_to_alloc;
+       }
+}
+
+    void yyFlexLexer::yy_push_state( int new_state )
+{
+       if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) )
+               {
+               yy_size_t new_size;
+
+               (yy_start_stack_depth) += YY_START_STACK_INCR;
+               new_size = (yy_start_stack_depth) * sizeof( int );
+
+               if ( ! (yy_start_stack) )
+                       (yy_start_stack) = (int *) yyalloc(new_size  );
+
+               else
+                       (yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size  );
+
+               if ( ! (yy_start_stack) )
+                       YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+               }
+
+       (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START;
+
+       BEGIN(new_state);
+}
+
+    void yyFlexLexer::yy_pop_state()
+{
+       if ( --(yy_start_stack_ptr) < 0 )
+               YY_FATAL_ERROR( "start-condition stack underflow" );
+
+       BEGIN((yy_start_stack)[(yy_start_stack_ptr)]);
+}
+
+    int yyFlexLexer::yy_top_state()
+{
+       return (yy_start_stack)[(yy_start_stack_ptr) - 1];
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+void yyFlexLexer::LexerError( yyconst char msg[] )
+{
+       std::cerr << msg << std::endl;
+       exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+       do \
+               { \
+               /* Undo effects of setting up yytext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+               yytext[yyleng] = (yy_hold_char); \
+               (yy_c_buf_p) = yytext + yyless_macro_arg; \
+               (yy_hold_char) = *(yy_c_buf_p); \
+               *(yy_c_buf_p) = '\0'; \
+               yyleng = yyless_macro_arg; \
+               } \
+       while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+       register int i;
+       for ( i = 0; i < n; ++i )
+               s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+       register int n;
+       for ( n = 0; s[n]; ++n )
+               ;
+
+       return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size )
+{
+       return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size )
+{
+       /* The cast to (char *) in the following accommodates both
+        * implementations that use char* generic pointers, and those
+        * that use void* generic pointers.  It works with the latter
+        * because both ANSI C and C++ allow castless assignment from
+        * any pointer type to void*, and deal with argument conversions
+        * as though doing an assignment.
+        */
+       return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+       free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 291 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_lexer.l"
+
+
+
+// verbatim code copied to the bottom of the output
+
+
+
diff --git a/tools/elftosb/elftosb2/elftosb_lexer.l b/tools/elftosb/elftosb2/elftosb_lexer.l
new file mode 100644 (file)
index 0000000..23272b7
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+%option c++
+/* %option prefix="Elftosb" */
+%option yylineno
+%option never-interactive
+%option yyclass="ElftosbLexer"
+%option noyywrap
+
+%{
+#include "ElftosbLexer.h"
+#include <stdlib.h>
+#include <limits.h>
+#include <string>
+#include "HexValues.h"
+#include "Value.h"
+
+using namespace elftosb;
+
+//! Always executed before all other actions when a token is matched.
+//! This action just assign the first and last lines of the token to
+//! the current line. In most cases this is correct.
+#define YY_USER_ACTION do {                                                                    \
+                                                       m_location.m_firstLine = m_line;                \
+                                                       m_location.m_lastLine = m_line;         \
+                                               } while (0);
+
+%}
+
+DIGIT          [0-9]
+HEXDIGIT       [0-9a-fA-F]
+BINDIGIT       [0-1]
+IDENT          [a-zA-Z_][a-zA-Z0-9_]*
+ESC                    \\(x{HEXDIGIT}{2}|.)
+
+/* start conditions */
+%x blob mlcmt
+
+%%
+
+options                        { return TOK_OPTIONS; }
+constants              { return TOK_CONSTANTS; }
+sources                        { return TOK_SOURCES; }
+filters                        { return TOK_FILTERS; }
+section                        { return TOK_SECTION; }
+extern                 { return TOK_EXTERN; }
+from                   { return TOK_FROM; }
+raw                            { return TOK_RAW; }
+load                   { return TOK_LOAD; }
+jump                   { return TOK_JUMP; }
+call                   { return TOK_CALL; }
+mode                   { return TOK_MODE; }
+if                             { return TOK_IF; }
+else                   { return TOK_ELSE; }
+defined                        { return TOK_DEFINED; }
+info                   { return TOK_INFO; }
+warning                        { return TOK_WARNING; }
+error                  { return TOK_ERROR; }
+sizeof                 { return TOK_SIZEOF; }
+dcd                            { return TOK_DCD; }
+hab                            { return TOK_HAB; }
+ivt             { return TOK_IVT; }
+
+[whb]/[^a-zA-Z_0-9]                                    {       // must be followed by any non-ident char
+                                                                               int_size_t theSize;
+                                                                               switch (yytext[0])
+                                                                               {
+                                                                                       case 'w':
+                                                                                               theSize = kWordSize;
+                                                                                               break;
+                                                                                       case 'h':
+                                                                                               theSize = kHalfWordSize;
+                                                                                               break;
+                                                                                       case 'b':
+                                                                                               theSize = kByteSize;
+                                                                                               break;
+                                                                               }
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(0, theSize);
+                                                                               return TOK_INT_SIZE;
+                                                                       }
+                                                                       
+true|yes                                                       {
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(1, kWordSize);
+                                                                               return TOK_INT_LITERAL;
+                                                                       }
+
+false|no                                                       {
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(0, kWordSize);
+                                                                               return TOK_INT_LITERAL;
+                                                                       }
+
+{IDENT}                                                                {
+                                                                               m_symbolValue.m_str = new std::string(yytext);
+                                                                               if (isSourceName(m_symbolValue.m_str))
+                                                                               {
+                                                                                       return TOK_SOURCE_NAME;
+                                                                               }
+                                                                               else
+                                                                               {
+                                                                                       return TOK_IDENT;
+                                                                               }
+                                                                       }
+
+({DIGIT}+|0x{HEXDIGIT}+|0b{BINDIGIT}+)([ \t]*[GMK])?                   {
+                                                                               int base = 0;
+                                                                               uint32_t value;
+                                                                               int mult;
+                                                                               
+                                                                               // check for binary number
+                                                                               if (yytext[0] == '0' && yytext[1] == 'b')
+                                                                               {
+                                                                                       base = 2;               // this is a binary number
+                                                                                       yytext += 2;    // skip over the "0b"
+                                                                               }
+                                                                               
+                                                                               // convert value
+                                                                               value = (uint32_t)strtoul(yytext, NULL, base);
+                                                                               
+                                                                               // find multiplier
+                                                                               switch (yytext[strlen(yytext) - 1])
+                                                                               {
+                                                                                       case 'G':
+                                                                                               mult = 1024 * 1024 * 1024;
+                                                                                               break;
+                                                                                       case 'M':
+                                                                                               mult = 1024 * 1024;
+                                                                                               break;
+                                                                                       case 'K':
+                                                                                               mult = 1024;
+                                                                                               break;
+                                                                                       default:
+                                                                                               mult = 1;
+                                                                                               break;
+                                                                               }
+                                                                               
+                                                                               // set resulting symbol value
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(value * mult, kWordSize);
+                                                                               return TOK_INT_LITERAL;
+                                                                       }
+
+\'(.|ESC)\'|\'(.|ESC){2}\'|\'(.|ESC){4}\'              {
+                                                                               uint32_t value = 0;
+                                                                               int_size_t theSize;
+                                                                               int len = strlen(yytext);
+                                                                               if (len >= 3)
+                                                                               {
+                                                                                       value = yytext[1];
+                                                                                       theSize = kByteSize;
+                                                                               }
+                                                                               if (len >= 4)
+                                                                               {
+                                                                                       value = (value << 8) | yytext[2];
+                                                                                       theSize = kHalfWordSize;
+                                                                               }
+                                                                               if (len >= 6)
+                                                                               {
+                                                                                       value = (value << 8) | yytext[3];
+                                                                                       value = (value << 8) | yytext[4];
+                                                                                       theSize = kWordSize;
+                                                                               }
+                                                                               m_symbolValue.m_int = new elftosb::SizedIntegerValue(value, theSize);
+                                                                               return TOK_INT_LITERAL;
+                                                                       }
+
+\$[\.\*a-zA-Z0-9_\[\]\^\?\-]+                                  {
+                                                                               // remove $ from string
+                                                                               m_symbolValue.m_str = new std::string(&yytext[1]);
+                                                                               return TOK_SECTION_NAME;
+                                                                       }
+
+
+"/*"                                { BEGIN(mlcmt); }
+
+"{{"                                                           {
+                                                                               m_blob = new Blob();
+                                                                               m_blobFirstLine = yylineno;
+                                                                               BEGIN(blob);
+                                                                       }
+
+"{"                                                                    { return '{'; }
+
+"}"                                                                    { return '}'; }
+
+"("                                                                    { return '('; }
+
+")"                                                                    { return ')'; }
+
+"["                                                                    { return '['; }
+
+"]"                                                                    { return ']'; }
+
+"="                                                                    { return '='; }
+
+","                                                                    { return ','; }
+
+":"                                                                    { return ':'; }
+
+";"                                                                    { return ';'; }
+
+"."                                                                    { return '.'; }
+
+">"                                                                    { return '>'; }
+
+".."                                                           { return TOK_DOT_DOT; }
+
+"+"                                                                    { return '+'; }
+
+"-"                                                                    { return '-'; }
+
+"*"                                                                    { return '*'; }
+
+"/"                                                                    { return '/'; }
+
+"%"                                                                    { return '%'; }
+
+"~"                                                                    { return '~'; }
+
+"^"                                                                    { return '^'; }
+
+"<<"                                                           { return TOK_LSHIFT; }
+
+">>"                                                           { return TOK_RSHIFT; }
+
+"&"                                                                    { return '&'; }
+
+"|"                                                                    { return '|'; }
+
+"**"                                                           { return TOK_POWER; }
+
+"<"                                                                    { return '<'; }
+
+">="                                                           { return TOK_GEQ; }
+
+"<="                                                           { return TOK_LEQ; }
+
+"=="                                                           { return TOK_EQ; }
+
+"!="                                                           { return TOK_NEQ; }
+
+"&&"                                                           { return TOK_AND; }
+
+"||"                                                           { return TOK_OR; }
+
+"!"                                                                    { return '!'; }
+
+\"(ESC|[^\"])*\"                                       {
+                                                                               // get rid of quotes
+                                                                               yytext++;
+                                                                               yytext[strlen(yytext) - 1] = 0;
+//                                                                             processStringEscapes(yytext, yytext);
+                                                                               m_symbolValue.m_str = new std::string(yytext);
+                                                                               return TOK_STRING_LITERAL;
+                                                                       }
+
+<blob>{HEXDIGIT}{2}                                    {
+                                                                               uint8_t x = (hexCharToInt(yytext[0]) << 4) | hexCharToInt(yytext[1]);
+                                                                               m_blob->append(&x, 1);
+                                                                       }
+
+<blob>"}}"                                                     {
+                                                                               BEGIN(INITIAL);
+                                                                               m_symbolValue.m_blob = m_blob;
+                                                                               m_blob = NULL;
+                                                                               m_location.m_firstLine = m_blobFirstLine;
+                                                                               return TOK_BLOB;
+                                                                       }
+
+<mlcmt>\*\/                         {
+                                        // end of multi-line comment, return to initial state
+                                        BEGIN(INITIAL);
+                                    }
+
+
+(#|\/\/).*$                                                    /* absorb single-line comment */
+
+<*>[ \t]                                                       /* eat up whitespace in all states */
+
+<*>(\r\n|\r|\n)                                                {
+                                                                               /* eat up whitespace and count lines in all states */
+                                                                               m_line++;
+                                                                       }
+
+<mlcmt>.                            /* ignore all other chars in a multi-line comment */
+
+<*>.                                                           {
+                                                                               /* all other chars produce errors */
+                                                                               char msg[50];
+                                                                               sprintf(msg, "unexpected character '%c' on line %d", yytext[0], m_line);
+                                                                               LexerError(msg);
+                                                                       }
+
+%%
+
+// verbatim code copied to the bottom of the output
+
+
diff --git a/tools/elftosb/elftosb2/elftosb_parser.tab.cpp b/tools/elftosb/elftosb2/elftosb_parser.tab.cpp
new file mode 100644 (file)
index 0000000..731ca45
--- /dev/null
@@ -0,0 +1,2955 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Written by Richard Stallman by simplifying the original so called
+   ``semantic'' parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.1"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 1
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     TOK_IDENT = 258,
+     TOK_STRING_LITERAL = 259,
+     TOK_INT_LITERAL = 260,
+     TOK_SECTION_NAME = 261,
+     TOK_SOURCE_NAME = 262,
+     TOK_BLOB = 263,
+     TOK_DOT_DOT = 264,
+     TOK_AND = 265,
+     TOK_OR = 266,
+     TOK_GEQ = 267,
+     TOK_LEQ = 268,
+     TOK_EQ = 269,
+     TOK_NEQ = 270,
+     TOK_POWER = 271,
+     TOK_LSHIFT = 272,
+     TOK_RSHIFT = 273,
+     TOK_INT_SIZE = 274,
+     TOK_OPTIONS = 275,
+     TOK_CONSTANTS = 276,
+     TOK_SOURCES = 277,
+     TOK_FILTERS = 278,
+     TOK_SECTION = 279,
+     TOK_EXTERN = 280,
+     TOK_FROM = 281,
+     TOK_RAW = 282,
+     TOK_LOAD = 283,
+     TOK_JUMP = 284,
+     TOK_CALL = 285,
+     TOK_MODE = 286,
+     TOK_IF = 287,
+     TOK_ELSE = 288,
+     TOK_DEFINED = 289,
+     TOK_INFO = 290,
+     TOK_WARNING = 291,
+     TOK_ERROR = 292,
+     TOK_SIZEOF = 293,
+     TOK_DCD = 294,
+     TOK_HAB = 295,
+     TOK_IVT = 296,
+     UNARY_OP = 297
+   };
+#endif
+/* Tokens.  */
+#define TOK_IDENT 258
+#define TOK_STRING_LITERAL 259
+#define TOK_INT_LITERAL 260
+#define TOK_SECTION_NAME 261
+#define TOK_SOURCE_NAME 262
+#define TOK_BLOB 263
+#define TOK_DOT_DOT 264
+#define TOK_AND 265
+#define TOK_OR 266
+#define TOK_GEQ 267
+#define TOK_LEQ 268
+#define TOK_EQ 269
+#define TOK_NEQ 270
+#define TOK_POWER 271
+#define TOK_LSHIFT 272
+#define TOK_RSHIFT 273
+#define TOK_INT_SIZE 274
+#define TOK_OPTIONS 275
+#define TOK_CONSTANTS 276
+#define TOK_SOURCES 277
+#define TOK_FILTERS 278
+#define TOK_SECTION 279
+#define TOK_EXTERN 280
+#define TOK_FROM 281
+#define TOK_RAW 282
+#define TOK_LOAD 283
+#define TOK_JUMP 284
+#define TOK_CALL 285
+#define TOK_MODE 286
+#define TOK_IF 287
+#define TOK_ELSE 288
+#define TOK_DEFINED 289
+#define TOK_INFO 290
+#define TOK_WARNING 291
+#define TOK_ERROR 292
+#define TOK_SIZEOF 293
+#define TOK_DCD 294
+#define TOK_HAB 295
+#define TOK_IVT 296
+#define UNARY_OP 297
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 14 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+
+#include "ElftosbLexer.h"
+#include "ElftosbAST.h"
+#include "Logging.h"
+#include "Blob.h"
+#include "format_string.h"
+#include "Value.h"
+#include "ConversionController.h"
+
+using namespace elftosb;
+
+//! Our special location type.
+#define YYLTYPE token_loc_t
+
+// this indicates that we're using our own type. it should be unset automatically
+// but that's not working for some reason with the .hpp file.
+#if defined(YYLTYPE_IS_TRIVIAL)
+       #undef YYLTYPE_IS_TRIVIAL
+       #define YYLTYPE_IS_TRIVIAL 0
+#endif
+
+//! Default location action
+#define YYLLOC_DEFAULT(Current, Rhs, N)        \
+       do {            \
+               if (N)  \
+               {               \
+                       (Current).m_firstLine = YYRHSLOC(Rhs, 1).m_firstLine;   \
+                       (Current).m_lastLine = YYRHSLOC(Rhs, N).m_lastLine;             \
+               }               \
+               else    \
+               {               \
+                       (Current).m_firstLine = (Current).m_lastLine = YYRHSLOC(Rhs, 0).m_lastLine;     \
+               }               \
+       } while (0)
+
+//! Forward declaration of yylex().
+static int yylex(YYSTYPE * lvalp, YYLTYPE * yylloc, ElftosbLexer * lexer);
+
+// Forward declaration of error handling function.
+static void yyerror(YYLTYPE * yylloc, ElftosbLexer * lexer, CommandFileASTNode ** resultAST, const char * error);
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 58 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+typedef union YYSTYPE {
+       int m_num;
+       elftosb::SizedIntegerValue * m_int;
+       Blob * m_blob;
+       std::string * m_str;
+       elftosb::ASTNode * m_ast;       // must use full name here because this is put into *.tab.hpp
+} YYSTYPE;
+/* Line 196 of yacc.c.  */
+#line 220 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 219 of yacc.c.  */
+#line 244 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+
+#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
+# define YYSIZE_T __SIZE_TYPE__
+#endif
+#if ! defined (YYSIZE_T) && defined (size_t)
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T) && (defined (__STDC__) || defined (__cplusplus))
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+#endif
+#if ! defined (YYSIZE_T)
+# define YYSIZE_T unsigned int
+#endif
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+#if ! defined (yyoverflow) || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if defined (__STDC__) || defined (__cplusplus)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     define YYINCLUDED_STDLIB_H
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning. */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2005 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM ((YYSIZE_T) -1)
+#  endif
+#  ifdef __cplusplus
+extern "C" {
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if (! defined (malloc) && ! defined (YYINCLUDED_STDLIB_H) \
+       && (defined (__STDC__) || defined (__cplusplus)))
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if (! defined (free) && ! defined (YYINCLUDED_STDLIB_H) \
+       && (defined (__STDC__) || defined (__cplusplus)))
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifdef __cplusplus
+}
+#  endif
+# endif
+#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
+
+
+#if (! defined (yyoverflow) \
+     && (! defined (__cplusplus) \
+        || (defined (YYLTYPE_IS_TRIVIAL) && YYLTYPE_IS_TRIVIAL \
+             && defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  short int yyss;
+  YYSTYPE yyvs;
+    YYLTYPE yyls;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (short int) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+      + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined (__GNUC__) && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)             \
+      do                                       \
+       {                                       \
+         YYSIZE_T yyi;                         \
+         for (yyi = 0; yyi < (Count); yyi++)   \
+           (To)[yyi] = (From)[yyi];            \
+       }                                       \
+      while (0)
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)                                       \
+    do                                                                 \
+      {                                                                        \
+       YYSIZE_T yynewbytes;                                            \
+       YYCOPY (&yyptr->Stack, Stack, yysize);                          \
+       Stack = &yyptr->Stack;                                          \
+       yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+       yyptr += yynewbytes / sizeof (*yyptr);                          \
+      }                                                                        \
+    while (0)
+
+#endif
+
+#if defined (__STDC__) || defined (__cplusplus)
+   typedef signed char yysigned_char;
+#else
+   typedef short int yysigned_char;
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL  13
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   418
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS  66
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS  52
+/* YYNRULES -- Number of rules. */
+#define YYNRULES  133
+/* YYNRULES -- Number of states. */
+#define YYNSTATES  238
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   297
+
+#define YYTRANSLATE(YYX)                                               \
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const unsigned char yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    26,     2,     2,     2,    64,    23,     2,
+       9,    10,    62,    60,    16,    61,    20,    63,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    18,    17,
+      25,    15,    19,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    13,     2,    14,    59,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    11,    24,    12,    22,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,    21,    27,    28,    29,    30,    31,
+      32,    33,    34,    35,    36,    37,    38,    39,    40,    41,
+      42,    43,    44,    45,    46,    47,    48,    49,    50,    51,
+      52,    53,    54,    55,    56,    57,    58,    65
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const unsigned short int yyprhs[] =
+{
+       0,     0,     3,     6,     8,    11,    13,    15,    17,    22,
+      27,    29,    32,    35,    36,    40,    45,    47,    50,    54,
+      55,    59,    66,    70,    71,    73,    77,    81,    83,    86,
+      93,    96,    97,    99,   100,   104,   108,   110,   113,   116,
+     118,   120,   121,   123,   126,   129,   131,   132,   134,   136,
+     138,   140,   145,   147,   148,   150,   152,   154,   156,   160,
+     165,   167,   169,   171,   175,   177,   180,   183,   184,   186,
+     188,   193,   195,   196,   200,   205,   207,   209,   211,   213,
+     217,   220,   221,   227,   230,   233,   236,   239,   246,   251,
+     254,   255,   257,   261,   263,   265,   267,   271,   275,   279,
+     283,   287,   291,   295,   299,   302,   307,   311,   316,   318,
+     322,   325,   327,   329,   331,   335,   339,   343,   347,   351,
+     355,   359,   363,   367,   371,   375,   377,   381,   385,   390,
+     395,   400,   403,   406
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yysigned_char yyrhs[] =
+{
+      67,     0,    -1,    68,    82,    -1,    69,    -1,    68,    69,
+      -1,    70,    -1,    71,    -1,    75,    -1,    37,    11,    72,
+      12,    -1,    38,    11,    72,    12,    -1,    73,    -1,    72,
+      73,    -1,    74,    17,    -1,    -1,     3,    15,   111,    -1,
+      39,    11,    76,    12,    -1,    77,    -1,    76,    77,    -1,
+      78,    79,    17,    -1,    -1,     3,    15,     4,    -1,     3,
+      15,    42,     9,   113,    10,    -1,     9,    80,    10,    -1,
+      -1,    81,    -1,    80,    16,    81,    -1,     3,    15,   111,
+      -1,    83,    -1,    82,    83,    -1,    41,     9,   113,    84,
+      10,    86,    -1,    17,    85,    -1,    -1,    80,    -1,    -1,
+      30,    94,    17,    -1,    11,    87,    12,    -1,    88,    -1,
+      87,    88,    -1,    91,    17,    -1,   105,    -1,   108,    -1,
+      -1,    90,    -1,    89,    90,    -1,    91,    17,    -1,   108,
+      -1,    -1,    92,    -1,   101,    -1,   106,    -1,   107,    -1,
+      45,    93,    94,    97,    -1,    56,    -1,    -1,   113,    -1,
+       4,    -1,     7,    -1,    95,    -1,    95,    43,     7,    -1,
+       7,    13,    95,    14,    -1,     8,    -1,    99,    -1,    96,
+      -1,    95,    16,    96,    -1,     6,    -1,    22,     6,    -1,
+      19,    98,    -1,    -1,    20,    -1,   110,    -1,    58,     9,
+     100,    10,    -1,    80,    -1,    -1,   102,   103,   104,    -1,
+      57,   102,   110,   104,    -1,    47,    -1,    46,    -1,     7,
+      -1,   113,    -1,     9,   113,    10,    -1,     9,    10,    -1,
+      -1,    43,     7,    11,    89,    12,    -1,    48,   113,    -1,
+      52,     4,    -1,    53,     4,    -1,    54,     4,    -1,    49,
+     112,    11,    87,    12,   109,    -1,    50,    11,    87,    12,
+      -1,    50,   108,    -1,    -1,   113,    -1,   113,    21,   113,
+      -1,   112,    -1,     4,    -1,   113,    -1,   112,    25,   112,
+      -1,   112,    19,   112,    -1,   112,    29,   112,    -1,   112,
+      30,   112,    -1,   112,    31,   112,    -1,   112,    32,   112,
+      -1,   112,    27,   112,    -1,   112,    28,   112,    -1,    26,
+     112,    -1,     3,     9,     7,    10,    -1,     9,   112,    10,
+      -1,    51,     9,     3,    10,    -1,   115,    -1,     7,    18,
+       3,    -1,    18,     3,    -1,   117,    -1,     3,    -1,   114,
+      -1,   115,    60,   115,    -1,   115,    61,   115,    -1,   115,
+      62,   115,    -1,   115,    63,   115,    -1,   115,    64,   115,
+      -1,   115,    33,   115,    -1,   115,    23,   115,    -1,   115,
+      24,   115,    -1,   115,    59,   115,    -1,   115,    34,   115,
+      -1,   115,    35,   115,    -1,   116,    -1,   115,    20,    36,
+      -1,     9,   115,    10,    -1,    55,     9,   114,    10,    -1,
+      55,     9,     3,    10,    -1,    55,     9,     7,    10,    -1,
+      60,   115,    -1,    61,   115,    -1,     5,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const unsigned short int yyrline[] =
+{
+       0,   162,   162,   172,   178,   186,   187,   188,   191,   197,
+     203,   209,   216,   217,   220,   227,   233,   239,   247,   259,
+     262,   267,   275,   276,   280,   286,   294,   301,   307,   314,
+     329,   334,   340,   345,   351,   357,   365,   371,   379,   380,
+     381,   382,   385,   391,   399,   400,   401,   404,   405,   406,
+     407,   410,   433,   443,   445,   449,   454,   459,   464,   469,
+     474,   479,   484,   490,   498,   503,   510,   515,   521,   526,
+     532,   544,   545,   548,   577,   614,   615,   618,   623,   630,
+     631,   632,   635,   642,   649,   654,   659,   666,   677,   681,
+     688,   691,   696,   703,   707,   714,   718,   725,   732,   739,
+     746,   753,   760,   767,   774,   779,   784,   789,   796,   799,
+     804,   812,   816,   821,   832,   839,   846,   853,   860,   867,
+     874,   881,   888,   895,   902,   909,   913,   918,   923,   928,
+     933,   940,   944,   951
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "\"identifier\"", "\"string\"",
+  "\"integer\"", "\"section name\"", "\"source name\"",
+  "\"binary object\"", "'('", "')'", "'{'", "'}'", "'['", "']'", "'='",
+  "','", "';'", "':'", "'>'", "'.'", "\"..\"", "'~'", "'&'", "'|'", "'<'",
+  "'!'", "\"&&\"", "\"||\"", "\">=\"", "\"<=\"", "\"==\"", "\"!=\"",
+  "\"**\"", "\"<<\"", "\">>\"", "\"integer size\"", "\"options\"",
+  "\"constants\"", "\"sources\"", "\"filters\"", "\"section\"",
+  "\"extern\"", "\"from\"", "\"raw\"", "\"load\"", "\"jump\"", "\"call\"",
+  "\"mode\"", "\"if\"", "\"else\"", "\"defined\"", "\"info\"",
+  "\"warning\"", "\"error\"", "\"sizeof\"", "\"dcd\"", "\"hab\"",
+  "\"ivt\"", "'^'", "'+'", "'-'", "'*'", "'/'", "'%'", "UNARY_OP",
+  "$accept", "command_file", "blocks_list", "pre_section_block",
+  "options_block", "constants_block", "const_def_list",
+  "const_def_list_elem", "const_def", "sources_block", "source_def_list",
+  "source_def_list_elem", "source_def", "source_attrs_opt",
+  "source_attr_list", "source_attr_list_elem", "section_defs",
+  "section_def", "section_options_opt", "source_attr_list_opt",
+  "section_contents", "full_stmt_list", "full_stmt_list_elem",
+  "basic_stmt_list", "basic_stmt_list_elem", "basic_stmt", "load_stmt",
+  "dcd_opt", "load_data", "section_list", "section_list_elem",
+  "load_target_opt", "load_target", "ivt_def", "assignment_list_opt",
+  "call_stmt", "call_or_jump", "call_target", "call_arg_opt", "from_stmt",
+  "mode_stmt", "message_stmt", "if_stmt", "else_opt", "address_or_range",
+  "const_expr", "bool_expr", "int_const_expr", "symbol_ref", "expr",
+  "unary_expr", "int_value", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const unsigned short int yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,    40,
+      41,   123,   125,    91,    93,    61,    44,    59,    58,    62,
+      46,   264,   126,    38,   124,    60,    33,   265,   266,   267,
+     268,   269,   270,   271,   272,   273,   274,   275,   276,   277,
+     278,   279,   280,   281,   282,   283,   284,   285,   286,   287,
+     288,   289,   290,   291,   292,   293,   294,   295,   296,    94,
+      43,    45,    42,    47,    37,   297
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const unsigned char yyr1[] =
+{
+       0,    66,    67,    68,    68,    69,    69,    69,    70,    71,
+      72,    72,    73,    73,    74,    75,    76,    76,    77,    77,
+      78,    78,    79,    79,    80,    80,    81,    82,    82,    83,
+      84,    84,    85,    85,    86,    86,    87,    87,    88,    88,
+      88,    88,    89,    89,    90,    90,    90,    91,    91,    91,
+      91,    92,    93,    93,    94,    94,    94,    94,    94,    94,
+      94,    94,    95,    95,    96,    96,    97,    97,    98,    98,
+      99,   100,   100,   101,   101,   102,   102,   103,   103,   104,
+     104,   104,   105,   106,   107,   107,   107,   108,   109,   109,
+     109,   110,   110,   111,   111,   112,   112,   112,   112,   112,
+     112,   112,   112,   112,   112,   112,   112,   112,   113,   114,
+     114,   115,   115,   115,   115,   115,   115,   115,   115,   115,
+     115,   115,   115,   115,   115,   115,   115,   115,   115,   115,
+     115,   116,   116,   117
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const unsigned char yyr2[] =
+{
+       0,     2,     2,     1,     2,     1,     1,     1,     4,     4,
+       1,     2,     2,     0,     3,     4,     1,     2,     3,     0,
+       3,     6,     3,     0,     1,     3,     3,     1,     2,     6,
+       2,     0,     1,     0,     3,     3,     1,     2,     2,     1,
+       1,     0,     1,     2,     2,     1,     0,     1,     1,     1,
+       1,     4,     1,     0,     1,     1,     1,     1,     3,     4,
+       1,     1,     1,     3,     1,     2,     2,     0,     1,     1,
+       4,     1,     0,     3,     4,     1,     1,     1,     1,     3,
+       2,     0,     5,     2,     2,     2,     2,     6,     4,     2,
+       0,     1,     3,     1,     1,     1,     3,     3,     3,     3,
+       3,     3,     3,     3,     2,     4,     3,     4,     1,     3,
+       2,     1,     1,     1,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     1,     3,     3,     4,     4,
+       4,     2,     2,     1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const unsigned char yydefact[] =
+{
+       0,     0,     0,     0,     0,     0,     3,     5,     6,     7,
+      13,    13,    19,     1,     0,     4,     2,    27,     0,     0,
+      10,     0,     0,     0,     0,    16,    23,     0,    28,     0,
+       8,    11,    12,     9,     0,    15,    17,     0,     0,   112,
+     133,     0,     0,     0,     0,     0,     0,    31,   113,   108,
+     125,   111,   112,    94,     0,     0,     0,    14,    93,    95,
+      20,     0,     0,     0,    24,    18,     0,     0,   110,     0,
+     131,   132,    33,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   108,   104,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    22,     0,   109,   127,     0,     0,     0,    32,    30,
+       0,   126,   120,   121,   119,   123,   124,   122,   114,   115,
+     116,   117,   118,     0,   106,     0,    97,    96,   102,   103,
+      98,    99,   100,   101,     0,    26,    25,   129,   130,   128,
+      41,     0,    29,   105,   107,    21,     0,    53,    76,    75,
+       0,     0,     0,     0,     0,     0,     0,    36,     0,    47,
+      48,     0,    39,    49,    50,    40,    55,    64,    56,    60,
+       0,     0,     0,    57,    62,    61,    54,     0,    52,     0,
+      83,     0,    84,    85,    86,     0,    35,    37,    38,    77,
+      81,    78,     0,    65,    72,    34,     0,     0,    46,    67,
+      41,    81,    91,     0,    73,     0,    71,     0,    63,    58,
+       0,    42,     0,    45,     0,    51,     0,    74,     0,    80,
+       0,    59,    70,    82,    43,    44,    68,    66,    69,    90,
+      92,    79,     0,    87,    41,    89,     0,    88
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+      -1,     4,     5,     6,     7,     8,    19,    20,    21,     9,
+      24,    25,    26,    38,    63,    64,    16,    17,    73,   109,
+     142,   156,   157,   210,   211,   158,   159,   179,   172,   173,
+     174,   215,   227,   175,   207,   160,   161,   190,   204,   162,
+     163,   164,   165,   233,   201,    57,    58,    59,    48,    49,
+      50,    51
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -181
+static const short int yypact[] =
+{
+     128,    17,    25,    48,    69,   123,  -181,  -181,  -181,  -181,
+      96,    96,   101,  -181,    80,  -181,    68,  -181,   112,    85,
+    -181,   115,    89,   114,    91,  -181,   124,    30,  -181,    47,
+    -181,  -181,  -181,  -181,    11,  -181,  -181,   134,   125,  -181,
+    -181,   133,    30,   140,   144,    30,    30,   153,  -181,   225,
+    -181,  -181,   148,  -181,    61,    61,   162,  -181,   359,  -181,
+    -181,   164,   159,    22,  -181,  -181,   172,   121,  -181,     9,
+    -181,  -181,   134,   168,   143,    30,    30,    30,    30,    30,
+      30,    30,    30,    30,    30,    30,   179,   303,   121,  -181,
+     194,    61,    61,    61,    61,    61,    61,    61,    61,    30,
+      47,  -181,   134,  -181,  -181,   188,     4,   200,   199,  -181,
+      56,  -181,   241,   231,   236,    86,    86,   247,    76,    76,
+     196,   196,   196,   208,  -181,   210,  -181,  -181,   373,   373,
+    -181,  -181,  -181,  -181,   216,  -181,  -181,  -181,  -181,  -181,
+     314,     2,  -181,  -181,  -181,  -181,   220,   175,  -181,  -181,
+      30,    61,   228,   230,   237,    28,   147,  -181,   223,  -181,
+    -181,   108,  -181,  -181,  -181,  -181,  -181,  -181,    92,  -181,
+     240,   243,   233,    15,  -181,  -181,  -181,   242,  -181,     2,
+    -181,   345,  -181,  -181,  -181,    30,  -181,  -181,  -181,   133,
+     246,  -181,     7,  -181,   134,  -181,     7,   250,   361,   244,
+     314,   246,   248,    16,  -181,   104,   199,   252,  -181,  -181,
+     190,  -181,   251,  -181,    75,  -181,   160,  -181,    30,  -181,
+     261,  -181,  -181,  -181,  -181,  -181,  -181,  -181,  -181,   222,
+    -181,  -181,     6,  -181,   314,  -181,   176,  -181
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const short int yypgoto[] =
+{
+    -181,  -181,  -181,   268,  -181,  -181,   266,   106,  -181,  -181,
+    -181,   254,  -181,  -181,   -70,   177,  -181,   267,  -181,  -181,
+    -181,  -151,  -155,  -181,   107,  -180,  -181,  -181,   127,   122,
+     129,  -181,  -181,  -181,  -181,  -181,   163,  -181,   118,  -181,
+    -181,  -181,   -21,  -181,   109,   221,   -51,   -27,   257,   270,
+    -181,  -181
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
+static const unsigned char yytable[] =
+{
+      47,   187,   108,    87,    89,    39,   166,    40,   167,   168,
+     169,    42,   105,   167,   138,    60,   106,   234,   212,    39,
+      43,    40,    66,    41,   170,    42,   219,    43,    10,   170,
+     212,   196,   101,    39,    43,    40,    11,    41,   102,    42,
+     126,   127,   128,   129,   130,   131,   132,   133,    43,   216,
+      52,    53,    40,    61,    41,   151,    54,    44,   197,    12,
+     171,   187,    45,    46,    52,    43,    40,   140,    41,    13,
+      54,    44,   134,    55,   148,   149,    45,    46,    39,    43,
+      40,   187,    41,   236,    42,    44,   141,    55,    18,    27,
+      45,    46,    18,    43,    23,   226,    74,    30,    56,    18,
+     181,    33,    44,    35,    23,   192,    74,    45,    46,    14,
+      66,    39,    56,    40,   176,   189,    44,    42,   221,    77,
+     196,    45,    46,   180,   206,    31,    43,    29,    31,    34,
+      44,   104,    32,    37,   191,    45,    46,    62,    83,    84,
+      85,    74,    65,    68,    75,    76,    81,    82,    83,    84,
+      85,    66,   176,    69,    77,    78,    79,    86,   202,   186,
+       1,     2,     3,    44,    14,     1,     2,     3,    45,    46,
+      72,    90,   229,    99,   100,   103,   220,   213,   110,   111,
+      80,    81,    82,    83,    84,    85,   123,   202,   237,   213,
+     146,   230,   147,   148,   149,   150,   151,   125,   137,   152,
+     153,   154,   223,   146,   155,   147,   148,   149,   150,   151,
+     139,   235,   152,   153,   154,   102,    74,   155,   143,   146,
+     144,   147,   148,   149,   150,   151,   145,   177,   152,   153,
+     154,   178,   182,   155,   183,   147,   148,   149,   150,   151,
+     188,   184,   152,   153,   154,    74,   193,   155,    75,    76,
+     195,    74,   194,   198,    75,   203,    74,   209,    77,    78,
+      79,    74,   222,   214,    77,    78,    79,    74,   225,   218,
+      75,   231,   232,    15,    77,    78,    79,    22,    36,   136,
+      77,    78,    79,    28,    80,    81,    82,    83,    84,    85,
+      80,    81,    82,    83,    84,    85,    81,    82,    83,    84,
+      85,    81,    82,    83,    84,    85,   199,    81,    82,    83,
+      84,    85,    67,   124,   205,    70,    71,   224,   185,   217,
+       0,   135,    91,   228,    88,   208,   107,     0,    92,     0,
+      93,    94,    95,    96,    97,    98,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   112,   113,   114,   115,   116,
+     117,   118,   119,   120,   121,   122,   200,   146,     0,   147,
+     148,   149,   150,   151,    91,     0,   152,   153,   154,     0,
+      92,   155,    93,    94,    95,    96,    97,    98,    91,     0,
+       0,     0,     0,     0,    92,     0,    93,    94,    95,    96,
+      97,    98,    91,     0,     0,     0,     0,     0,    92,     0,
+       0,     0,    95,    96,    97,    98,   147,   148,   149,   150,
+     151,     0,     0,   152,   153,   154,     0,     0,   155
+};
+
+static const short int yycheck[] =
+{
+      27,   156,    72,    54,    55,     3,     4,     5,     6,     7,
+       8,     9,     3,     6,    10,     4,     7,    11,   198,     3,
+      18,     5,    18,     7,    22,     9,    10,    18,    11,    22,
+     210,    16,    10,     3,    18,     5,    11,     7,    16,     9,
+      91,    92,    93,    94,    95,    96,    97,    98,    18,   200,
+       3,     4,     5,    42,     7,    49,     9,    55,    43,    11,
+      58,   216,    60,    61,     3,    18,     5,    11,     7,     0,
+       9,    55,    99,    26,    46,    47,    60,    61,     3,    18,
+       5,   236,     7,   234,     9,    55,    30,    26,     3,     9,
+      60,    61,     3,    18,     3,    20,    20,    12,    51,     3,
+     151,    12,    55,    12,     3,    13,    20,    60,    61,    41,
+      18,     3,    51,     5,   141,     7,    55,     9,    14,    33,
+      16,    60,    61,   150,   194,    19,    18,    15,    22,    15,
+      55,    10,    17,     9,   161,    60,    61,     3,    62,    63,
+      64,    20,    17,     3,    23,    24,    60,    61,    62,    63,
+      64,    18,   179,     9,    33,    34,    35,     9,   185,    12,
+      37,    38,    39,    55,    41,    37,    38,    39,    60,    61,
+      17,     9,    12,     9,    15,     3,   203,   198,    10,    36,
+      59,    60,    61,    62,    63,    64,     7,   214,    12,   210,
+      43,   218,    45,    46,    47,    48,    49,     3,    10,    52,
+      53,    54,    12,    43,    57,    45,    46,    47,    48,    49,
+      10,   232,    52,    53,    54,    16,    20,    57,    10,    43,
+      10,    45,    46,    47,    48,    49,    10,     7,    52,    53,
+      54,    56,     4,    57,     4,    45,    46,    47,    48,    49,
+      17,     4,    52,    53,    54,    20,     6,    57,    23,    24,
+      17,    20,     9,    11,    23,     9,    20,     7,    33,    34,
+      35,    20,    10,    19,    33,    34,    35,    20,    17,    21,
+      23,    10,    50,     5,    33,    34,    35,    11,    24,   102,
+      33,    34,    35,    16,    59,    60,    61,    62,    63,    64,
+      59,    60,    61,    62,    63,    64,    60,    61,    62,    63,
+      64,    60,    61,    62,    63,    64,   179,    60,    61,    62,
+      63,    64,    42,    10,   192,    45,    46,   210,   155,   201,
+      -1,   100,    19,   214,    54,   196,    69,    -1,    25,    -1,
+      27,    28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    75,    76,    77,    78,    79,
+      80,    81,    82,    83,    84,    85,    11,    43,    -1,    45,
+      46,    47,    48,    49,    19,    -1,    52,    53,    54,    -1,
+      25,    57,    27,    28,    29,    30,    31,    32,    19,    -1,
+      -1,    -1,    -1,    -1,    25,    -1,    27,    28,    29,    30,
+      31,    32,    19,    -1,    -1,    -1,    -1,    -1,    25,    -1,
+      -1,    -1,    29,    30,    31,    32,    45,    46,    47,    48,
+      49,    -1,    -1,    52,    53,    54,    -1,    -1,    57
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const unsigned char yystos[] =
+{
+       0,    37,    38,    39,    67,    68,    69,    70,    71,    75,
+      11,    11,    11,     0,    41,    69,    82,    83,     3,    72,
+      73,    74,    72,     3,    76,    77,    78,     9,    83,    15,
+      12,    73,    17,    12,    15,    12,    77,     9,    79,     3,
+       5,     7,     9,    18,    55,    60,    61,   113,   114,   115,
+     116,   117,     3,     4,     9,    26,    51,   111,   112,   113,
+       4,    42,     3,    80,    81,    17,    18,   115,     3,     9,
+     115,   115,    17,    84,    20,    23,    24,    33,    34,    35,
+      59,    60,    61,    62,    63,    64,     9,   112,   115,   112,
+       9,    19,    25,    27,    28,    29,    30,    31,    32,     9,
+      15,    10,    16,     3,    10,     3,     7,   114,    80,    85,
+      10,    36,   115,   115,   115,   115,   115,   115,   115,   115,
+     115,   115,   115,     7,    10,     3,   112,   112,   112,   112,
+     112,   112,   112,   112,   113,   111,    81,    10,    10,    10,
+      11,    30,    86,    10,    10,    10,    43,    45,    46,    47,
+      48,    49,    52,    53,    54,    57,    87,    88,    91,    92,
+     101,   102,   105,   106,   107,   108,     4,     6,     7,     8,
+      22,    58,    94,    95,    96,    99,   113,     7,    56,    93,
+     113,   112,     4,     4,     4,   102,    12,    88,    17,     7,
+     103,   113,    13,     6,     9,    17,    16,    43,    11,    94,
+      11,   110,   113,     9,   104,    95,    80,   100,    96,     7,
+      89,    90,    91,   108,    19,    97,    87,   104,    21,    10,
+     113,    14,    10,    12,    90,    17,    20,    98,   110,    12,
+     113,    10,    50,   109,    11,   108,    87,    12
+};
+
+#define yyerrok                (yyerrstatus = 0)
+#define yyclearin      (yychar = YYEMPTY)
+#define YYEMPTY                (-2)
+#define YYEOF          0
+
+#define YYACCEPT       goto yyacceptlab
+#define YYABORT                goto yyabortlab
+#define YYERROR                goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL         goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                 \
+do                                                             \
+  if (yychar == YYEMPTY && yylen == 1)                         \
+    {                                                          \
+      yychar = (Token);                                                \
+      yylval = (Value);                                                \
+      yytoken = YYTRANSLATE (yychar);                          \
+      YYPOPSTACK;                                              \
+      goto yybackup;                                           \
+    }                                                          \
+  else                                                         \
+    {                                                          \
+      yyerror (&yylloc, lexer, resultAST, YY_("syntax error: cannot back up")); \
+      YYERROR;                                                 \
+    }                                                          \
+while (0)
+
+
+#define YYTERROR       1
+#define YYERRCODE      256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)                               \
+    do                                                                 \
+      if (N)                                                           \
+       {                                                               \
+         (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;        \
+         (Current).first_column = YYRHSLOC (Rhs, 1).first_column;      \
+         (Current).last_line    = YYRHSLOC (Rhs, N).last_line;         \
+         (Current).last_column  = YYRHSLOC (Rhs, N).last_column;       \
+       }                                                               \
+      else                                                             \
+       {                                                               \
+         (Current).first_line   = (Current).last_line   =              \
+           YYRHSLOC (Rhs, 0).last_line;                                \
+         (Current).first_column = (Current).last_column =              \
+           YYRHSLOC (Rhs, 0).last_column;                              \
+       }                                                               \
+    while (0)
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)                 \
+     fprintf (File, "%d.%d-%d.%d",                     \
+              (Loc).first_line, (Loc).first_column,    \
+              (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, lexer)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)                       \
+do {                                           \
+  if (yydebug)                                 \
+    YYFPRINTF Args;                            \
+} while (0)
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)         \
+do {                                                           \
+  if (yydebug)                                                 \
+    {                                                          \
+      YYFPRINTF (stderr, "%s ", Title);                                \
+      yysymprint (stderr,                                      \
+                  Type, Value, Location);      \
+      YYFPRINTF (stderr, "\n");                                        \
+    }                                                          \
+} while (0)
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_stack_print (short int *bottom, short int *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    short int *bottom;
+    short int *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (/* Nothing. */; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)                           \
+do {                                                           \
+  if (yydebug)                                                 \
+    yy_stack_print ((Bottom), (Top));                          \
+} while (0)
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yy_reduce_print (int yyrule)
+#else
+static void
+yy_reduce_print (yyrule)
+    int yyrule;
+#endif
+{
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu), ",
+             yyrule - 1, yylno);
+  /* Print the symbols being reduced, and their result.  */
+  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
+    YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]);
+  YYFPRINTF (stderr, "-> %s\n", yytname[yyr1[yyrule]]);
+}
+
+# define YY_REDUCE_PRINT(Rule)         \
+do {                                   \
+  if (yydebug)                         \
+    yy_reduce_print (Rule);            \
+} while (0)
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef        YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+\f
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined (__GLIBC__) && defined (_STRING_H)
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+static YYSIZE_T
+#   if defined (__STDC__) || defined (__cplusplus)
+yystrlen (const char *yystr)
+#   else
+yystrlen (yystr)
+     const char *yystr;
+#   endif
+{
+  const char *yys = yystr;
+
+  while (*yys++ != '\0')
+    continue;
+
+  return yys - yystr - 1;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+static char *
+#   if defined (__STDC__) || defined (__cplusplus)
+yystpcpy (char *yydest, const char *yysrc)
+#   else
+yystpcpy (yydest, yysrc)
+     char *yydest;
+     const char *yysrc;
+#   endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      size_t yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+       switch (*++yyp)
+         {
+         case '\'':
+         case ',':
+           goto do_not_strip_quotes;
+
+         case '\\':
+           if (*++yyp != '\\')
+             goto do_not_strip_quotes;
+           /* Fall through.  */
+         default:
+           if (yyres)
+             yyres[yyn] = *yyp;
+           yyn++;
+           break;
+
+         case '"':
+           if (yyres)
+             yyres[yyn] = '\0';
+           return yyn;
+         }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* YYERROR_VERBOSE */
+
+\f
+
+#if YYDEBUG
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+#else
+static void
+yysymprint (yyoutput, yytype, yyvaluep, yylocationp)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+  (void) yylocationp;
+
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# endif
+  switch (yytype)
+    {
+      default:
+        break;
+    }
+  YYFPRINTF (yyoutput, ")");
+}
+
+#endif /* ! YYDEBUG */
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+#if defined (__STDC__) || defined (__cplusplus)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+#endif
+{
+  /* Pacify ``unused variable'' warnings.  */
+  (void) yyvaluep;
+  (void) yylocationp;
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+      case 3: /* "\"identifier\"" */
+#line 158 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+        { delete (yyvaluep->m_str); };
+#line 1209 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+        break;
+      case 4: /* "\"string\"" */
+#line 158 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+        { delete (yyvaluep->m_str); };
+#line 1214 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+        break;
+      case 5: /* "\"integer\"" */
+#line 158 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+        { delete (yyvaluep->m_int); };
+#line 1219 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+        break;
+      case 6: /* "\"section name\"" */
+#line 158 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+        { delete (yyvaluep->m_str); };
+#line 1224 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+        break;
+      case 7: /* "\"source name\"" */
+#line 158 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+        { delete (yyvaluep->m_str); };
+#line 1229 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+        break;
+      case 8: /* "\"binary object\"" */
+#line 158 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+        { delete (yyvaluep->m_blob); };
+#line 1234 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+        break;
+      case 36: /* "\"integer size\"" */
+#line 158 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+        { delete (yyvaluep->m_int); };
+#line 1239 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+        break;
+
+      default:
+        break;
+    }
+}
+\f
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM);
+# else
+int yyparse ();
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int yyparse (ElftosbLexer * lexer, CommandFileASTNode ** resultAST);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+# if defined (__STDC__) || defined (__cplusplus)
+int yyparse (void *YYPARSE_PARAM)
+# else
+int yyparse (YYPARSE_PARAM)
+  void *YYPARSE_PARAM;
+# endif
+#else /* ! YYPARSE_PARAM */
+#if defined (__STDC__) || defined (__cplusplus)
+int
+yyparse (ElftosbLexer * lexer, CommandFileASTNode ** resultAST)
+#else
+int
+yyparse (lexer, resultAST)
+    ElftosbLexer * lexer;
+    CommandFileASTNode ** resultAST;
+#endif
+#endif
+{
+  /* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+/* Location data for the look-ahead symbol.  */
+YYLTYPE yylloc;
+
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  short int yyssa[YYINITDEPTH];
+  short int *yyss = yyssa;
+  short int *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+  /* The locations where the error started and ended. */
+  YYLTYPE yyerror_range[2];
+
+#define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+  /* When reducing, the number of symbols on the RHS of the reduced
+     rule.  */
+  int yylen;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;            /* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+  yylsp = yyls;
+#if YYLTYPE_IS_TRIVIAL
+  /* Initialize the default location before parsing starts.  */
+  yylloc.first_line   = yylloc.last_line   = 1;
+  yylloc.first_column = yylloc.last_column = 0;
+#endif
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed. so pushing a state here evens the stacks.
+     */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+       /* Give user a chance to reallocate the stack. Use copies of
+          these so that the &'s don't force the real ones into
+          memory.  */
+       YYSTYPE *yyvs1 = yyvs;
+       short int *yyss1 = yyss;
+       YYLTYPE *yyls1 = yyls;
+
+       /* Each stack pointer address is followed by the size of the
+          data in use in that stack, in bytes.  This used to be a
+          conditional around just the two extra args, but that might
+          be undefined if yyoverflow is a macro.  */
+       yyoverflow (YY_("memory exhausted"),
+                   &yyss1, yysize * sizeof (*yyssp),
+                   &yyvs1, yysize * sizeof (*yyvsp),
+                   &yyls1, yysize * sizeof (*yylsp),
+                   &yystacksize);
+       yyls = yyls1;
+       yyss = yyss1;
+       yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+       goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+       yystacksize = YYMAXDEPTH;
+
+      {
+       short int *yyss1 = yyss;
+       union yyalloc *yyptr =
+         (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+       if (! yyptr)
+         goto yyexhaustedlab;
+       YYSTACK_RELOCATE (yyss);
+       YYSTACK_RELOCATE (yyvs);
+       YYSTACK_RELOCATE (yyls);
+#  undef YYSTACK_RELOCATE
+       if (yyss1 != yyssa)
+         YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+                 (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+       YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+/* Do appropriate processing given the current state.  */
+/* Read a look-ahead token if we need one and don't already have one.  */
+/* yyresume: */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+       goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the token being shifted unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  *++yyvsp = yylval;
+  *++yylsp = yylloc;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+  /* Default location. */
+  YYLLOC_DEFAULT (yyloc, yylsp - yylen, yylen);
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 163 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       CommandFileASTNode * commandFile = new CommandFileASTNode();
+                                                       commandFile->setBlocks(dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast)));
+                                                       commandFile->setSections(dynamic_cast<ListASTNode*>((yyvsp[0].m_ast)));
+                                                       commandFile->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       *resultAST = commandFile;
+                                               ;}
+    break;
+
+  case 3:
+#line 173 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ListASTNode * list = new ListASTNode();
+                                                       list->appendNode((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = list;
+                                               ;}
+    break;
+
+  case 4:
+#line 179 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast))->appendNode((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                               ;}
+    break;
+
+  case 5:
+#line 186 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 6:
+#line 187 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 7:
+#line 188 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 8:
+#line 192 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new OptionsBlockASTNode(dynamic_cast<ListASTNode *>((yyvsp[-1].m_ast)));
+                                                       ;}
+    break;
+
+  case 9:
+#line 198 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new ConstantsBlockASTNode(dynamic_cast<ListASTNode *>((yyvsp[-1].m_ast)));
+                                                       ;}
+    break;
+
+  case 10:
+#line 204 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = list;
+                                                       ;}
+    break;
+
+  case 11:
+#line 210 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast))->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                                       ;}
+    break;
+
+  case 12:
+#line 216 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[-1].m_ast); ;}
+    break;
+
+  case 13:
+#line 217 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 14:
+#line 221 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new AssignmentASTNode((yyvsp[-2].m_str), (yyvsp[0].m_ast));
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 15:
+#line 228 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = new SourcesBlockASTNode(dynamic_cast<ListASTNode *>((yyvsp[-1].m_ast)));
+                                               ;}
+    break;
+
+  case 16:
+#line 234 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ListASTNode * list = new ListASTNode();
+                                                       list->appendNode((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = list;
+                                               ;}
+    break;
+
+  case 17:
+#line 240 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast))->appendNode((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                               ;}
+    break;
+
+  case 18:
+#line 248 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               // tell the lexer that this is the name of a source file
+                                                               SourceDefASTNode * node = dynamic_cast<SourceDefASTNode*>((yyvsp[-2].m_ast));
+                                                               if ((yyvsp[-1].m_ast))
+                                                               {
+                                                                       node->setAttributes(dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast)));
+                                                               }
+                                                               node->setLocation(node->getLocation(), (yylsp[0]));
+                                                               lexer->addSourceName(node->getName());
+                                                               (yyval.m_ast) = (yyvsp[-2].m_ast);
+                                                       ;}
+    break;
+
+  case 19:
+#line 259 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 20:
+#line 263 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new PathSourceDefASTNode((yyvsp[-2].m_str), (yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 21:
+#line 268 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new ExternSourceDefASTNode((yyvsp[-5].m_str), dynamic_cast<ExprASTNode*>((yyvsp[-1].m_ast)));
+                                                               (yyval.m_ast)->setLocation((yylsp[-5]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 22:
+#line 275 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[-1].m_ast); ;}
+    break;
+
+  case 23:
+#line 276 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 24:
+#line 281 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = list;
+                                                       ;}
+    break;
+
+  case 25:
+#line 287 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               dynamic_cast<ListASTNode*>((yyvsp[-2].m_ast))->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = (yyvsp[-2].m_ast);
+                                                       ;}
+    break;
+
+  case 26:
+#line 295 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new AssignmentASTNode((yyvsp[-2].m_str), (yyvsp[0].m_ast));
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 27:
+#line 302 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = list;
+                                                       ;}
+    break;
+
+  case 28:
+#line 308 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast))->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                                       ;}
+    break;
+
+  case 29:
+#line 315 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               SectionContentsASTNode * sectionNode = dynamic_cast<SectionContentsASTNode*>((yyvsp[0].m_ast));
+                                                               if (sectionNode)
+                                                               {
+                                                                       ExprASTNode * exprNode = dynamic_cast<ExprASTNode*>((yyvsp[-3].m_ast));
+                                                                       sectionNode->setSectionNumberExpr(exprNode);
+                                                                       sectionNode->setOptions(dynamic_cast<ListASTNode*>((yyvsp[-2].m_ast)));
+                                                                       sectionNode->setLocation((yylsp[-5]), sectionNode->getLocation());
+                                                               }
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 30:
+#line 330 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 31:
+#line 334 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = NULL;
+                                                       ;}
+    break;
+
+  case 32:
+#line 341 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 33:
+#line 345 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = NULL;
+                                                       ;}
+    break;
+
+  case 34:
+#line 352 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               DataSectionContentsASTNode * dataSection = new DataSectionContentsASTNode((yyvsp[-1].m_ast));
+                                                               dataSection->setLocation((yylsp[-2]), (yylsp[0]));
+                                                               (yyval.m_ast) = dataSection;
+                                                       ;}
+    break;
+
+  case 35:
+#line 358 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ListASTNode * listNode = dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast));
+                                                               (yyval.m_ast) = new BootableSectionContentsASTNode(listNode);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 36:
+#line 366 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = list;
+                                                       ;}
+    break;
+
+  case 37:
+#line 372 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast))->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                                       ;}
+    break;
+
+  case 38:
+#line 379 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[-1].m_ast); ;}
+    break;
+
+  case 39:
+#line 380 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 40:
+#line 381 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 41:
+#line 382 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 42:
+#line 386 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = list;
+                                                       ;}
+    break;
+
+  case 43:
+#line 392 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast))->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                                       ;}
+    break;
+
+  case 44:
+#line 399 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[-1].m_ast); ;}
+    break;
+
+  case 45:
+#line 400 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 46:
+#line 401 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 47:
+#line 404 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 48:
+#line 405 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 49:
+#line 406 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 50:
+#line 407 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 51:
+#line 411 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               LoadStatementASTNode * stmt = new LoadStatementASTNode();
+                                                               stmt->setData((yyvsp[-1].m_ast));
+                                                               stmt->setTarget((yyvsp[0].m_ast));
+                                                               // set dcd load flag if the "dcd" keyword was present.
+                                                               if ((yyvsp[-2].m_num))
+                                                               {
+                                                                       stmt->setDCDLoad(true);
+                                                               }
+                                                               // set char locations for the statement
+                                                               if ((yyvsp[0].m_ast))
+                                                               {
+                                                                       stmt->setLocation((yylsp[-3]), (yylsp[0]));
+                                                               }
+                                                               else
+                                                               {
+                                                                       stmt->setLocation((yylsp[-3]), (yylsp[-1]));
+                                                               }
+                                                               (yyval.m_ast) = stmt;
+                                                       ;}
+    break;
+
+  case 52:
+#line 434 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               if (!elftosb::g_enableHABSupport)
+                                                               {
+                                                                       yyerror(&yylloc, lexer, resultAST, "HAB features not supported with the selected family");
+                                                                       YYABORT;
+                                                               }
+                                                               
+                                                               (yyval.m_num) = 1;
+                                                       ;}
+    break;
+
+  case 53:
+#line 443 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_num) = 0; ;}
+    break;
+
+  case 54:
+#line 446 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 55:
+#line 450 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new StringConstASTNode((yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 56:
+#line 455 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SourceASTNode((yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 57:
+#line 460 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>((yyvsp[0].m_ast)));
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 58:
+#line 465 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>((yyvsp[-2].m_ast)), (yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 59:
+#line 470 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast)), (yyvsp[-3].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[-3]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 60:
+#line 475 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new BlobConstASTNode((yyvsp[0].m_blob));
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 61:
+#line 480 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ;}
+    break;
+
+  case 62:
+#line 485 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = list;
+                                                       ;}
+    break;
+
+  case 63:
+#line 491 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               dynamic_cast<ListASTNode*>((yyvsp[-2].m_ast))->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = (yyvsp[-2].m_ast);
+                                                       ;}
+    break;
+
+  case 64:
+#line 499 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SectionASTNode((yyvsp[0].m_str), SectionASTNode::kInclude);
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 65:
+#line 504 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SectionASTNode((yyvsp[0].m_str), SectionASTNode::kExclude);
+                                                               (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 66:
+#line 511 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 67:
+#line 515 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new NaturalLocationASTNode();
+//                                                             $$->setLocation();
+                                                       ;}
+    break;
+
+  case 68:
+#line 522 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new NaturalLocationASTNode();
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 69:
+#line 527 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 70:
+#line 533 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               IVTConstASTNode * ivt = new IVTConstASTNode();
+                                                               if ((yyvsp[-1].m_ast))
+                                                               {
+                                                                       ivt->setFieldAssignments(dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast)));
+                                                               }
+                                                               ivt->setLocation((yylsp[-3]), (yylsp[0]));
+                                                               (yyval.m_ast) = ivt;
+                                                       ;}
+    break;
+
+  case 71:
+#line 544 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 72:
+#line 545 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 73:
+#line 549 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               CallStatementASTNode * stmt = new CallStatementASTNode();
+                                                               switch ((yyvsp[-2].m_num))
+                                                               {
+                                                                       case 1:
+                                                                               stmt->setCallType(CallStatementASTNode::kCallType);
+                                                                               break;
+                                                                       case 2:
+                                                                               stmt->setCallType(CallStatementASTNode::kJumpType);
+                                                                               break;
+                                                                       default:
+                                                                               yyerror(&yylloc, lexer, resultAST, "invalid call_or_jump value");
+                                                                               YYABORT;
+                                                                               break;
+                                                               }
+                                                               stmt->setTarget((yyvsp[-1].m_ast));
+                                                               stmt->setArgument((yyvsp[0].m_ast));
+                                                               stmt->setIsHAB(false);
+                                                               if ((yyvsp[0].m_ast))
+                                                               {
+                                                                       stmt->setLocation((yylsp[-2]), (yylsp[0]));
+                                                               }
+                                                               else
+                                                               {
+                                                                       stmt->setLocation((yylsp[-2]), (yylsp[-1]));
+                                                               }
+                                                               (yyval.m_ast) = stmt;
+                                                       ;}
+    break;
+
+  case 74:
+#line 578 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               if (!elftosb::g_enableHABSupport)
+                                                               {
+                                                                       yyerror(&yylloc, lexer, resultAST, "HAB features not supported with the selected family");
+                                                                       YYABORT;
+                                                               }
+                                                               
+                                                               CallStatementASTNode * stmt = new CallStatementASTNode();
+                                                               switch ((yyvsp[-2].m_num))
+                                                               {
+                                                                       case 1:
+                                                                               stmt->setCallType(CallStatementASTNode::kCallType);
+                                                                               break;
+                                                                       case 2:
+                                                                               stmt->setCallType(CallStatementASTNode::kJumpType);
+                                                                               break;
+                                                                       default:
+                                                                               yyerror(&yylloc, lexer, resultAST, "invalid call_or_jump value");
+                                                                               YYABORT;
+                                                                               break;
+                                                               }
+                                                               stmt->setTarget((yyvsp[-1].m_ast));
+                                                               stmt->setArgument((yyvsp[0].m_ast));
+                                                               stmt->setIsHAB(true);
+                                                               if ((yyvsp[0].m_ast))
+                                                               {
+                                                                       stmt->setLocation((yylsp[-3]), (yylsp[0]));
+                                                               }
+                                                               else
+                                                               {
+                                                                       stmt->setLocation((yylsp[-3]), (yylsp[-1]));
+                                                               }
+                                                               (yyval.m_ast) = stmt;
+                                                       ;}
+    break;
+
+  case 75:
+#line 614 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_num) = 1; ;}
+    break;
+
+  case 76:
+#line 615 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_num) = 2; ;}
+    break;
+
+  case 77:
+#line 619 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SymbolASTNode(NULL, (yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 78:
+#line 624 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new AddressRangeASTNode((yyvsp[0].m_ast), NULL);
+                                                               (yyval.m_ast)->setLocation((yyvsp[0].m_ast));
+                                                       ;}
+    break;
+
+  case 79:
+#line 630 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[-1].m_ast); ;}
+    break;
+
+  case 80:
+#line 631 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 81:
+#line 632 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 82:
+#line 636 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new FromStatementASTNode((yyvsp[-3].m_str), dynamic_cast<ListASTNode*>((yyvsp[-1].m_ast)));
+                                                               (yyval.m_ast)->setLocation((yylsp[-4]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 83:
+#line 643 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new ModeStatementASTNode(dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast)));
+                                                               (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 84:
+#line 650 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new MessageStatementASTNode(MessageStatementASTNode::kInfo, (yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 85:
+#line 655 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new MessageStatementASTNode(MessageStatementASTNode::kWarning, (yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 86:
+#line 660 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new MessageStatementASTNode(MessageStatementASTNode::kError, (yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 87:
+#line 667 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               IfStatementASTNode * ifStmt = new IfStatementASTNode();
+                                                               ifStmt->setConditionExpr(dynamic_cast<ExprASTNode*>((yyvsp[-4].m_ast)));
+                                                               ifStmt->setIfStatements(dynamic_cast<ListASTNode*>((yyvsp[-2].m_ast)));
+                                                               ifStmt->setElseStatements(dynamic_cast<ListASTNode*>((yyvsp[0].m_ast)));
+                                                               ifStmt->setLocation((yylsp[-5]), (yylsp[0]));
+                                                               (yyval.m_ast) = ifStmt;
+                                                       ;}
+    break;
+
+  case 88:
+#line 678 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                                       ;}
+    break;
+
+  case 89:
+#line 682 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = list;
+                                                               (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 90:
+#line 688 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = NULL; ;}
+    break;
+
+  case 91:
+#line 692 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new AddressRangeASTNode((yyvsp[0].m_ast), NULL);
+                                                               (yyval.m_ast)->setLocation((yyvsp[0].m_ast));
+                                                       ;}
+    break;
+
+  case 92:
+#line 697 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new AddressRangeASTNode((yyvsp[-2].m_ast), (yyvsp[0].m_ast));
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 93:
+#line 704 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 94:
+#line 708 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new StringConstASTNode((yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 95:
+#line 715 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = (yyvsp[0].m_ast);
+                                               ;}
+    break;
+
+  case 96:
+#line 719 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kLessThan, right);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 97:
+#line 726 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kGreaterThan, right);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 98:
+#line 733 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kGreaterThanEqual, right);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 99:
+#line 740 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kLessThanEqual, right);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 100:
+#line 747 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kEqual, right);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 101:
+#line 754 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kNotEqual, right);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 102:
+#line 761 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBooleanAnd, right);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 103:
+#line 768 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                       (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBooleanOr, right);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 104:
+#line 775 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = new BooleanNotExprASTNode(dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast)));
+                                                       (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 105:
+#line 780 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = new SourceFileFunctionASTNode((yyvsp[-3].m_str), (yyvsp[-1].m_str));
+                                                       (yyval.m_ast)->setLocation((yylsp[-3]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 106:
+#line 785 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                                       (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 107:
+#line 790 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = new DefinedOperatorASTNode((yyvsp[-1].m_str));
+                                                       (yyval.m_ast)->setLocation((yylsp[-3]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 108:
+#line 796 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    { (yyval.m_ast) = (yyvsp[0].m_ast); ;}
+    break;
+
+  case 109:
+#line 800 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SymbolASTNode((yyvsp[0].m_str), (yyvsp[-2].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 110:
+#line 805 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SymbolASTNode((yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 111:
+#line 813 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 112:
+#line 817 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new VariableExprASTNode((yyvsp[0].m_str));
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 113:
+#line 822 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new SymbolRefExprASTNode(dynamic_cast<SymbolASTNode*>((yyvsp[0].m_ast)));
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+  case 114:
+#line 833 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kAdd, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 115:
+#line 840 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kSubtract, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 116:
+#line 847 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kMultiply, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 117:
+#line 854 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kDivide, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 118:
+#line 861 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kModulus, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 119:
+#line 868 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kPower, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 120:
+#line 875 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseAnd, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 121:
+#line 882 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseOr, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 122:
+#line 889 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseXor, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 123:
+#line 896 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kShiftLeft, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 124:
+#line 903 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast));
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast));
+                                                               (yyval.m_ast) = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kShiftRight, right);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 125:
+#line 910 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 126:
+#line 914 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new IntSizeExprASTNode(dynamic_cast<ExprASTNode*>((yyvsp[-2].m_ast)), (yyvsp[0].m_int)->getWordSize());
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 127:
+#line 919 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[-1].m_ast);
+                                                               (yyval.m_ast)->setLocation((yylsp[-2]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 128:
+#line 924 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = new SizeofOperatorASTNode(dynamic_cast<SymbolASTNode*>((yyvsp[-1].m_ast)));
+                                                       (yyval.m_ast)->setLocation((yylsp[-3]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 129:
+#line 929 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = new SizeofOperatorASTNode((yyvsp[-1].m_str));
+                                                       (yyval.m_ast)->setLocation((yylsp[-3]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 130:
+#line 934 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                       (yyval.m_ast) = new SizeofOperatorASTNode((yyvsp[-1].m_str));
+                                                       (yyval.m_ast)->setLocation((yylsp[-3]), (yylsp[0]));
+                                               ;}
+    break;
+
+  case 131:
+#line 941 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = (yyvsp[0].m_ast);
+                                                       ;}
+    break;
+
+  case 132:
+#line 945 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new NegativeExprASTNode(dynamic_cast<ExprASTNode*>((yyvsp[0].m_ast)));
+                                                               (yyval.m_ast)->setLocation((yylsp[-1]), (yylsp[0]));
+                                                       ;}
+    break;
+
+  case 133:
+#line 952 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+    {
+                                                               (yyval.m_ast) = new IntConstExprASTNode((yyvsp[0].m_int)->getValue(), (yyvsp[0].m_int)->getWordSize());
+                                                               (yyval.m_ast)->setLocation((yylsp[0]));
+                                                       ;}
+    break;
+
+
+      default: break;
+    }
+
+/* Line 1126 of yacc.c.  */
+#line 2663 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.cpp"
+\f
+  yyvsp -= yylen;
+  yyssp -= yylen;
+  yylsp -= yylen;
+
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+  *++yylsp = yyloc;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if YYERROR_VERBOSE
+      yyn = yypact[yystate];
+
+      if (YYPACT_NINF < yyn && yyn < YYLAST)
+       {
+         int yytype = YYTRANSLATE (yychar);
+         YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+         YYSIZE_T yysize = yysize0;
+         YYSIZE_T yysize1;
+         int yysize_overflow = 0;
+         char *yymsg = 0;
+#        define YYERROR_VERBOSE_ARGS_MAXIMUM 5
+         char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+         int yyx;
+
+#if 0
+         /* This is so xgettext sees the translatable formats that are
+            constructed on the fly.  */
+         YY_("syntax error, unexpected %s");
+         YY_("syntax error, unexpected %s, expecting %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+         YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+#endif
+         char *yyfmt;
+         char const *yyf;
+         static char const yyunexpected[] = "syntax error, unexpected %s";
+         static char const yyexpecting[] = ", expecting %s";
+         static char const yyor[] = " or %s";
+         char yyformat[sizeof yyunexpected
+                       + sizeof yyexpecting - 1
+                       + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+                          * (sizeof yyor - 1))];
+         char const *yyprefix = yyexpecting;
+
+         /* Start YYX at -YYN if negative to avoid negative indexes in
+            YYCHECK.  */
+         int yyxbegin = yyn < 0 ? -yyn : 0;
+
+         /* Stay within bounds of both yycheck and yytname.  */
+         int yychecklim = YYLAST - yyn;
+         int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+         int yycount = 1;
+
+         yyarg[0] = yytname[yytype];
+         yyfmt = yystpcpy (yyformat, yyunexpected);
+
+         for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+           if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+             {
+               if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                 {
+                   yycount = 1;
+                   yysize = yysize0;
+                   yyformat[sizeof yyunexpected - 1] = '\0';
+                   break;
+                 }
+               yyarg[yycount++] = yytname[yyx];
+               yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+               yysize_overflow |= yysize1 < yysize;
+               yysize = yysize1;
+               yyfmt = yystpcpy (yyfmt, yyprefix);
+               yyprefix = yyor;
+             }
+
+         yyf = YY_(yyformat);
+         yysize1 = yysize + yystrlen (yyf);
+         yysize_overflow |= yysize1 < yysize;
+         yysize = yysize1;
+
+         if (!yysize_overflow && yysize <= YYSTACK_ALLOC_MAXIMUM)
+           yymsg = (char *) YYSTACK_ALLOC (yysize);
+         if (yymsg)
+           {
+             /* Avoid sprintf, as that infringes on the user's name space.
+                Don't have undefined behavior even if the translation
+                produced a string with the wrong number of "%s"s.  */
+             char *yyp = yymsg;
+             int yyi = 0;
+             while ((*yyp = *yyf))
+               {
+                 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+                   {
+                     yyp += yytnamerr (yyp, yyarg[yyi++]);
+                     yyf += 2;
+                   }
+                 else
+                   {
+                     yyp++;
+                     yyf++;
+                   }
+               }
+             yyerror (&yylloc, lexer, resultAST, yymsg);
+             YYSTACK_FREE (yymsg);
+           }
+         else
+           {
+             yyerror (&yylloc, lexer, resultAST, YY_("syntax error"));
+             goto yyexhaustedlab;
+           }
+       }
+      else
+#endif /* YYERROR_VERBOSE */
+       yyerror (&yylloc, lexer, resultAST, YY_("syntax error"));
+    }
+
+  yyerror_range[0] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+        error, discard it.  */
+
+      if (yychar <= YYEOF)
+        {
+         /* Return failure if at end of input.  */
+         if (yychar == YYEOF)
+           YYABORT;
+        }
+      else
+       {
+         yydestruct ("Error: discarding", yytoken, &yylval, &yylloc);
+         yychar = YYEMPTY;
+       }
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (0)
+     goto yyerrorlab;
+
+  yyerror_range[0] = yylsp[1-yylen];
+  yylsp -= yylen;
+  yyvsp -= yylen;
+  yyssp -= yylen;
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;     /* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+       {
+         yyn += YYTERROR;
+         if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+           {
+             yyn = yytable[yyn];
+             if (0 < yyn)
+               break;
+           }
+       }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+       YYABORT;
+
+      yyerror_range[0] = *yylsp;
+      yydestruct ("Error: popping", yystos[yystate], yyvsp, yylsp);
+      YYPOPSTACK;
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+  yyerror_range[1] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the look-ahead.  YYLOC is available though. */
+  YYLLOC_DEFAULT (yyloc, yyerror_range - 1, 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token. */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (&yylloc, lexer, resultAST, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+                yytoken, &yylval, &yylloc);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+                 yystos[*yyssp], yyvsp, yylsp);
+      YYPOPSTACK;
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+  return yyresult;
+}
+
+
+#line 958 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+
+
+/* code goes here */
+
+static int yylex(YYSTYPE * lvalp, YYLTYPE * yylloc, ElftosbLexer * lexer)
+{
+       int token = lexer->yylex();
+       *yylloc = lexer->getLocation();
+       lexer->getSymbolValue(lvalp);
+       return token;
+}
+
+static void yyerror(YYLTYPE * yylloc, ElftosbLexer * lexer, CommandFileASTNode ** resultAST, const char * error)
+{
+       throw syntax_error(format_string("line %d: %s\n", yylloc->m_firstLine, error));
+}
+
+
diff --git a/tools/elftosb/elftosb2/elftosb_parser.tab.hpp b/tools/elftosb/elftosb2/elftosb_parser.tab.hpp
new file mode 100644 (file)
index 0000000..4ee45c4
--- /dev/null
@@ -0,0 +1,152 @@
+/* A Bison parser, made by GNU Bison 2.1.  */
+
+/* Skeleton parser for Yacc-like parsing with Bison,
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, when this file is copied by Bison into a
+   Bison output file, you may use that output file without restriction.
+   This special exception was added by the Free Software Foundation
+   in version 1.24 of Bison.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     TOK_IDENT = 258,
+     TOK_STRING_LITERAL = 259,
+     TOK_INT_LITERAL = 260,
+     TOK_SECTION_NAME = 261,
+     TOK_SOURCE_NAME = 262,
+     TOK_BLOB = 263,
+     TOK_DOT_DOT = 264,
+     TOK_AND = 265,
+     TOK_OR = 266,
+     TOK_GEQ = 267,
+     TOK_LEQ = 268,
+     TOK_EQ = 269,
+     TOK_NEQ = 270,
+     TOK_POWER = 271,
+     TOK_LSHIFT = 272,
+     TOK_RSHIFT = 273,
+     TOK_INT_SIZE = 274,
+     TOK_OPTIONS = 275,
+     TOK_CONSTANTS = 276,
+     TOK_SOURCES = 277,
+     TOK_FILTERS = 278,
+     TOK_SECTION = 279,
+     TOK_EXTERN = 280,
+     TOK_FROM = 281,
+     TOK_RAW = 282,
+     TOK_LOAD = 283,
+     TOK_JUMP = 284,
+     TOK_CALL = 285,
+     TOK_MODE = 286,
+     TOK_IF = 287,
+     TOK_ELSE = 288,
+     TOK_DEFINED = 289,
+     TOK_INFO = 290,
+     TOK_WARNING = 291,
+     TOK_ERROR = 292,
+     TOK_SIZEOF = 293,
+     TOK_DCD = 294,
+     TOK_HAB = 295,
+     TOK_IVT = 296,
+     UNARY_OP = 297
+   };
+#endif
+/* Tokens.  */
+#define TOK_IDENT 258
+#define TOK_STRING_LITERAL 259
+#define TOK_INT_LITERAL 260
+#define TOK_SECTION_NAME 261
+#define TOK_SOURCE_NAME 262
+#define TOK_BLOB 263
+#define TOK_DOT_DOT 264
+#define TOK_AND 265
+#define TOK_OR 266
+#define TOK_GEQ 267
+#define TOK_LEQ 268
+#define TOK_EQ 269
+#define TOK_NEQ 270
+#define TOK_POWER 271
+#define TOK_LSHIFT 272
+#define TOK_RSHIFT 273
+#define TOK_INT_SIZE 274
+#define TOK_OPTIONS 275
+#define TOK_CONSTANTS 276
+#define TOK_SOURCES 277
+#define TOK_FILTERS 278
+#define TOK_SECTION 279
+#define TOK_EXTERN 280
+#define TOK_FROM 281
+#define TOK_RAW 282
+#define TOK_LOAD 283
+#define TOK_JUMP 284
+#define TOK_CALL 285
+#define TOK_MODE 286
+#define TOK_IF 287
+#define TOK_ELSE 288
+#define TOK_DEFINED 289
+#define TOK_INFO 290
+#define TOK_WARNING 291
+#define TOK_ERROR 292
+#define TOK_SIZEOF 293
+#define TOK_DCD 294
+#define TOK_HAB 295
+#define TOK_IVT 296
+#define UNARY_OP 297
+
+
+
+
+#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
+#line 58 "/Users/creed/projects/fsl/fromsvr/elftosb/elftosb2/elftosb_parser.y"
+typedef union YYSTYPE {
+       int m_num;
+       elftosb::SizedIntegerValue * m_int;
+       Blob * m_blob;
+       std::string * m_str;
+       elftosb::ASTNode * m_ast;       // must use full name here because this is put into *.tab.hpp
+} YYSTYPE;
+/* Line 1447 of yacc.c.  */
+#line 130 "/Users/creed/projects/fsl/fromsvr/elftosb/build/elftosb.build/Debug/elftosb.build/DerivedSources/elftosb_parser.tab.hpp"
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+
diff --git a/tools/elftosb/elftosb2/elftosb_parser.y b/tools/elftosb/elftosb2/elftosb_parser.y
new file mode 100644 (file)
index 0000000..7c33652
--- /dev/null
@@ -0,0 +1,978 @@
+/*
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+/* write header with token defines */
+%defines
+
+/* make it reentrant */
+%pure-parser
+
+/* put more info in error messages */
+%error-verbose
+
+/* enable location processing */
+%locations
+
+%{
+#include "ElftosbLexer.h"
+#include "ElftosbAST.h"
+#include "Logging.h"
+#include "Blob.h"
+#include "format_string.h"
+#include "Value.h"
+#include "ConversionController.h"
+
+using namespace elftosb;
+
+//! Our special location type.
+#define YYLTYPE token_loc_t
+
+// this indicates that we're using our own type. it should be unset automatically
+// but that's not working for some reason with the .hpp file.
+#if defined(YYLTYPE_IS_TRIVIAL)
+       #undef YYLTYPE_IS_TRIVIAL
+       #define YYLTYPE_IS_TRIVIAL 0
+#endif
+
+//! Default location action
+#define YYLLOC_DEFAULT(Current, Rhs, N)        \
+       do {            \
+               if (N)  \
+               {               \
+                       (Current).m_firstLine = YYRHSLOC(Rhs, 1).m_firstLine;   \
+                       (Current).m_lastLine = YYRHSLOC(Rhs, N).m_lastLine;             \
+               }               \
+               else    \
+               {               \
+                       (Current).m_firstLine = (Current).m_lastLine = YYRHSLOC(Rhs, 0).m_lastLine;     \
+               }               \
+       } while (0)
+
+//! Forward declaration of yylex().
+static int yylex(YYSTYPE * lvalp, YYLTYPE * yylloc, ElftosbLexer * lexer);
+
+// Forward declaration of error handling function.
+static void yyerror(YYLTYPE * yylloc, ElftosbLexer * lexer, CommandFileASTNode ** resultAST, const char * error);
+
+%}
+
+/* symbol types */
+%union {
+       int m_num;
+       elftosb::SizedIntegerValue * m_int;
+       Blob * m_blob;
+       std::string * m_str;
+       elftosb::ASTNode * m_ast;       // must use full name here because this is put into *.tab.hpp
+}
+
+/* extra parameters for the parser and lexer */
+%parse-param   {ElftosbLexer * lexer}
+%parse-param   {CommandFileASTNode ** resultAST}
+%lex-param             {ElftosbLexer * lexer}
+
+/* token definitions */
+%token <m_str> TOK_IDENT                       "identifier"
+%token <m_str> TOK_STRING_LITERAL      "string"
+%token <m_int> TOK_INT_LITERAL         "integer"
+%token <m_str> TOK_SECTION_NAME                "section name"
+%token <m_str> TOK_SOURCE_NAME         "source name"
+%token <m_blob> TOK_BLOB                       "binary object"
+%token '('
+%token ')'
+%token '{'
+%token '}'
+%token '['
+%token ']'
+%token '='
+%token ','
+%token ';'
+%token ':'
+%token '>'
+%token '.'
+%token TOK_DOT_DOT                             ".."
+%token '~'
+%token '&'
+%token '|'
+%token '<'
+%token '>'
+%token '!'
+%token TOK_AND                                 "&&"
+%token TOK_OR                                  "||"
+%token TOK_GEQ                                 ">="
+%token TOK_LEQ                                 "<="
+%token TOK_EQ                                  "=="
+%token TOK_NEQ                                 "!="
+%token TOK_POWER                               "**"
+%token TOK_LSHIFT                              "<<"
+%token TOK_RSHIFT                              ">>"
+%token <m_int> TOK_INT_SIZE            "integer size"
+%token TOK_OPTIONS             "options"
+%token TOK_CONSTANTS   "constants"
+%token TOK_SOURCES             "sources"
+%token TOK_FILTERS             "filters"
+%token TOK_SECTION             "section"
+%token TOK_EXTERN              "extern"
+%token TOK_FROM                        "from"
+%token TOK_RAW                 "raw"
+%token TOK_LOAD                        "load"
+%token TOK_JUMP                        "jump"
+%token TOK_CALL                        "call"
+%token TOK_MODE                        "mode"
+%token TOK_IF                  "if"
+%token TOK_ELSE                        "else"
+%token TOK_DEFINED             "defined"
+%token TOK_INFO                        "info"
+%token TOK_WARNING             "warning"
+%token TOK_ERROR               "error"
+%token TOK_SIZEOF              "sizeof"
+%token TOK_DCD                 "dcd"
+%token TOK_HAB                 "hab"
+%token TOK_IVT                 "ivt"
+
+/* operator precedence */
+%left "&&" "||"
+%left '>' '<' ">=" "<=" "==" "!="
+%left '|'
+%left '^'
+%left '&'
+%left "<<" ">>"
+%left "**"
+%left '+' '-'
+%left '*' '/' '%'
+%left '.'
+%right UNARY_OP
+
+/* nonterminal types - most nonterminal symbols are subclasses of ASTNode */
+%type <m_ast> command_file blocks_list pre_section_block options_block const_def_list const_def_list_elem
+%type <m_ast> const_def const_expr expr int_const_expr unary_expr int_value constants_block
+%type <m_ast> sources_block source_def_list source_def_list_elem source_def
+%type <m_ast> section_defs section_def section_contents full_stmt_list full_stmt_list_elem
+%type <m_ast> basic_stmt load_stmt call_stmt from_stmt load_data load_target call_target
+%type <m_ast> address_or_range load_target_opt call_arg_opt basic_stmt_list basic_stmt_list_elem
+%type <m_ast> source_attr_list source_attr_list_elem source_attrs_opt
+%type <m_ast> section_list section_list_elem symbol_ref mode_stmt
+%type <m_ast> section_options_opt source_attr_list_opt
+%type <m_ast> if_stmt else_opt message_stmt
+%type <m_ast> bool_expr ivt_def assignment_list_opt
+
+%type <m_num> call_or_jump dcd_opt
+
+%destructor { delete $$; } TOK_IDENT TOK_STRING_LITERAL TOK_SECTION_NAME TOK_SOURCE_NAME TOK_BLOB TOK_INT_SIZE TOK_INT_LITERAL
+
+%%
+
+command_file   :       blocks_list section_defs
+                                               {
+                                                       CommandFileASTNode * commandFile = new CommandFileASTNode();
+                                                       commandFile->setBlocks(dynamic_cast<ListASTNode*>($1));
+                                                       commandFile->setSections(dynamic_cast<ListASTNode*>($2));
+                                                       commandFile->setLocation(@1, @2);
+                                                       *resultAST = commandFile;
+                                               }
+                               ;
+
+blocks_list            :       pre_section_block
+                                               {
+                                                       ListASTNode * list = new ListASTNode();
+                                                       list->appendNode($1);
+                                                       $$ = list;
+                                               }
+                               |       blocks_list pre_section_block
+                                               {
+                                                       dynamic_cast<ListASTNode*>($1)->appendNode($2);
+                                                       $$ = $1;
+                                               }
+                               ;
+
+pre_section_block
+                               :       options_block                   { $$ = $1; }
+                               |       constants_block                 { $$ = $1; }
+                               |       sources_block                   { $$ = $1; }
+                               ;
+
+options_block          :       "options" '{' const_def_list '}'
+                                                       {
+                                                               $$ = new OptionsBlockASTNode(dynamic_cast<ListASTNode *>($3));
+                                                       }
+                                       ;
+
+constants_block                :       "constants" '{' const_def_list '}'
+                                                       {
+                                                               $$ = new ConstantsBlockASTNode(dynamic_cast<ListASTNode *>($3));
+                                                       }
+                                       ;
+
+const_def_list         :       const_def_list_elem
+                                                       {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode($1);
+                                                               $$ = list;
+                                                       }
+                                       |       const_def_list const_def_list_elem
+                                                       {
+                                                               dynamic_cast<ListASTNode*>($1)->appendNode($2);
+                                                               $$ = $1;
+                                                       }
+                                       ;
+
+const_def_list_elem    :       const_def ';'           { $$ = $1; }
+                                       |       /* empty */                     { $$ = NULL; }
+                                       ;
+
+const_def                      :       TOK_IDENT '=' const_expr
+                                                       {
+                                                               $$ = new AssignmentASTNode($1, $3);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                                       ;
+
+sources_block  :       "sources" '{' source_def_list '}'
+                                               {
+                                                       $$ = new SourcesBlockASTNode(dynamic_cast<ListASTNode *>($3));
+                                               }
+                               ;
+
+source_def_list        :       source_def_list_elem
+                                               {
+                                                       ListASTNode * list = new ListASTNode();
+                                                       list->appendNode($1);
+                                                       $$ = list;
+                                               }
+                               |       source_def_list source_def_list_elem
+                                               {
+                                                       dynamic_cast<ListASTNode*>($1)->appendNode($2);
+                                                       $$ = $1;
+                                               }
+                               ;
+
+source_def_list_elem
+                               :               source_def source_attrs_opt ';'
+                                                       {
+                                                               // tell the lexer that this is the name of a source file
+                                                               SourceDefASTNode * node = dynamic_cast<SourceDefASTNode*>($1);
+                                                               if ($2)
+                                                               {
+                                                                       node->setAttributes(dynamic_cast<ListASTNode*>($2));
+                                                               }
+                                                               node->setLocation(node->getLocation(), @3);
+                                                               lexer->addSourceName(node->getName());
+                                                               $$ = $1;
+                                                       }
+                               |               /* empty */             { $$ = NULL; }
+                               ;
+
+source_def             :               TOK_IDENT '=' TOK_STRING_LITERAL
+                                                       {
+                                                               $$ = new PathSourceDefASTNode($1, $3);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               TOK_IDENT '=' "extern" '(' int_const_expr ')'
+                                                       {
+                                                               $$ = new ExternSourceDefASTNode($1, dynamic_cast<ExprASTNode*>($5));
+                                                               $$->setLocation(@1, @6);
+                                                       }
+                               ;
+
+source_attrs_opt
+                               :               '(' source_attr_list ')'                { $$ = $2; }
+                               |               /* empty */                                             { $$ = NULL; }
+                               ;
+
+source_attr_list
+                               :               source_attr_list_elem
+                                                       {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode($1);
+                                                               $$ = list;
+                                                       }
+                               |               source_attr_list ',' source_attr_list_elem
+                                                       {
+                                                               dynamic_cast<ListASTNode*>($1)->appendNode($3);
+                                                               $$ = $1;
+                                                       }
+                               ;
+                                               
+source_attr_list_elem
+                               :               TOK_IDENT '=' const_expr
+                                                       {
+                                                               $$ = new AssignmentASTNode($1, $3);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               ;
+
+section_defs   :               section_def
+                                                       {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode($1);
+                                                               $$ = list;
+                                                       }
+                               |               section_defs section_def
+                                                       {
+                                                               dynamic_cast<ListASTNode*>($1)->appendNode($2);
+                                                               $$ = $1;
+                                                       }
+                               ;
+
+section_def            :               "section" '(' int_const_expr section_options_opt ')' section_contents
+                                                       {
+                                                               SectionContentsASTNode * sectionNode = dynamic_cast<SectionContentsASTNode*>($6);
+                                                               if (sectionNode)
+                                                               {
+                                                                       ExprASTNode * exprNode = dynamic_cast<ExprASTNode*>($3);
+                                                                       sectionNode->setSectionNumberExpr(exprNode);
+                                                                       sectionNode->setOptions(dynamic_cast<ListASTNode*>($4));
+                                                                       sectionNode->setLocation(@1, sectionNode->getLocation());
+                                                               }
+                                                               $$ = $6;
+                                                       }
+                               ;
+
+section_options_opt
+                               :               ';' source_attr_list_opt
+                                                       {
+                                                               $$ = $2;
+                                                       }
+                               |               /* empty */
+                                                       {
+                                                               $$ = NULL;
+                                                       }
+                               ;
+
+source_attr_list_opt
+                               :               source_attr_list
+                                                       {
+                                                               $$ = $1;
+                                                       }
+                               |               /* empty */
+                                                       {
+                                                               $$ = NULL;
+                                                       }
+                               ;
+
+section_contents
+                               :               "<=" load_data ';'
+                                                       {
+                                                               DataSectionContentsASTNode * dataSection = new DataSectionContentsASTNode($2);
+                                                               dataSection->setLocation(@1, @3);
+                                                               $$ = dataSection;
+                                                       }
+                               |               '{' full_stmt_list '}'
+                                                       {
+                                                               ListASTNode * listNode = dynamic_cast<ListASTNode*>($2);
+                                                               $$ = new BootableSectionContentsASTNode(listNode);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               ;
+
+full_stmt_list :               full_stmt_list_elem
+                                                       {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode($1);
+                                                               $$ = list;
+                                                       }
+                               |               full_stmt_list full_stmt_list_elem
+                                                       {
+                                                               dynamic_cast<ListASTNode*>($1)->appendNode($2);
+                                                               $$ = $1;
+                                                       }
+                               ;
+
+full_stmt_list_elem
+                               :               basic_stmt ';'          { $$ = $1; }
+                               |               from_stmt                       { $$ = $1; }
+                               |               if_stmt                         { $$ = $1; }
+                               |               /* empty */                     { $$ = NULL; }
+                               ;
+
+basic_stmt_list        :               basic_stmt_list_elem
+                                                       {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode($1);
+                                                               $$ = list;
+                                                       }
+                               |               basic_stmt_list basic_stmt_list_elem
+                                                       {
+                                                               dynamic_cast<ListASTNode*>($1)->appendNode($2);
+                                                               $$ = $1;
+                                                       }
+                               ;
+
+basic_stmt_list_elem
+                               :               basic_stmt ';'          { $$ = $1; }
+                               |               if_stmt                         { $$ = $1; }
+                               |               /* empty */                     { $$ = NULL; }
+                               ;
+
+basic_stmt             :               load_stmt               { $$ = $1; }
+                               |               call_stmt               { $$ = $1; }
+                               |               mode_stmt               { $$ = $1; }
+                               |               message_stmt    { $$ = $1; }
+                               ;
+
+load_stmt              :               "load" dcd_opt load_data load_target_opt
+                                                       {
+                                                               LoadStatementASTNode * stmt = new LoadStatementASTNode();
+                                                               stmt->setData($3);
+                                                               stmt->setTarget($4);
+                                                               // set dcd load flag if the "dcd" keyword was present.
+                                                               if ($2)
+                                                               {
+                                                                       stmt->setDCDLoad(true);
+                                                               }
+                                                               // set char locations for the statement
+                                                               if ($4)
+                                                               {
+                                                                       stmt->setLocation(@1, @4);
+                                                               }
+                                                               else
+                                                               {
+                                                                       stmt->setLocation(@1, @3);
+                                                               }
+                                                               $$ = stmt;
+                                                       }
+                               ;
+
+dcd_opt                        :               "dcd"
+                                                       {
+                                                               if (!elftosb::g_enableHABSupport)
+                                                               {
+                                                                       yyerror(&yylloc, lexer, resultAST, "HAB features not supported with the selected family");
+                                                                       YYABORT;
+                                                               }
+                                                               
+                                                               $$ = 1;
+                                                       }
+                               |               /* empty */                     { $$ = 0; }
+
+load_data              :               int_const_expr
+                                                       {
+                                                               $$ = $1;
+                                                       }
+                               |               TOK_STRING_LITERAL
+                                                       {
+                                                               $$ = new StringConstASTNode($1);
+                                                               $$->setLocation(@1);
+                                                       }
+                               |               TOK_SOURCE_NAME
+                                                       {
+                                                               $$ = new SourceASTNode($1);
+                                                               $$->setLocation(@1);
+                                                       }
+                               |               section_list
+                                                       {
+                                                               $$ = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>($1));
+                                                               $$->setLocation(@1);
+                                                       }
+                               |               section_list "from" TOK_SOURCE_NAME
+                                                       {
+                                                               $$ = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>($1), $3);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               TOK_SOURCE_NAME '[' section_list ']'
+                                                       {
+                                                               $$ = new SectionMatchListASTNode(dynamic_cast<ListASTNode*>($3), $1);
+                                                               $$->setLocation(@1, @4);
+                                                       }
+                               |               TOK_BLOB
+                                                       {
+                                                               $$ = new BlobConstASTNode($1);
+                                                               $$->setLocation(@1);
+                                                       }
+                               |               ivt_def
+                                                       {
+                                                       }
+                               ;
+
+section_list   :               section_list_elem
+                                                       {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode($1);
+                                                               $$ = list;
+                                                       }
+                               |               section_list ',' section_list_elem
+                                                       {
+                                                               dynamic_cast<ListASTNode*>($1)->appendNode($3);
+                                                               $$ = $1;
+                                                       }
+                               ;
+
+section_list_elem
+                               :               TOK_SECTION_NAME
+                                                       {
+                                                               $$ = new SectionASTNode($1, SectionASTNode::kInclude);
+                                                               $$->setLocation(@1);
+                                                       }
+                               |               '~' TOK_SECTION_NAME
+                                                       {
+                                                               $$ = new SectionASTNode($2, SectionASTNode::kExclude);
+                                                               $$->setLocation(@1, @2);
+                                                       }
+                               ;
+
+load_target_opt        :               '>' load_target
+                                                       {
+                                                               $$ = $2;
+                                                       }
+                               |               /* empty */
+                                                       {
+                                                               $$ = new NaturalLocationASTNode();
+//                                                             $$->setLocation();
+                                                       }
+                               ;
+
+load_target            :               '.'
+                                                       {
+                                                               $$ = new NaturalLocationASTNode();
+                                                               $$->setLocation(@1);
+                                                       }
+                               |               address_or_range
+                                                       {
+                                                               $$ = $1;
+                                                       }
+                               ;
+
+ivt_def                        :               "ivt" '(' assignment_list_opt ')'
+                                                       {
+                                                               IVTConstASTNode * ivt = new IVTConstASTNode();
+                                                               if ($3)
+                                                               {
+                                                                       ivt->setFieldAssignments(dynamic_cast<ListASTNode*>($3));
+                                                               }
+                                                               ivt->setLocation(@1, @4);
+                                                               $$ = ivt;
+                                                       }
+                               ;
+
+assignment_list_opt    :       source_attr_list                { $$ = $1; }
+                                       |       /* empty */                             { $$ = NULL; }
+                                       ;
+
+call_stmt              :               call_or_jump call_target call_arg_opt
+                                                       {
+                                                               CallStatementASTNode * stmt = new CallStatementASTNode();
+                                                               switch ($1)
+                                                               {
+                                                                       case 1:
+                                                                               stmt->setCallType(CallStatementASTNode::kCallType);
+                                                                               break;
+                                                                       case 2:
+                                                                               stmt->setCallType(CallStatementASTNode::kJumpType);
+                                                                               break;
+                                                                       default:
+                                                                               yyerror(&yylloc, lexer, resultAST, "invalid call_or_jump value");
+                                                                               YYABORT;
+                                                                               break;
+                                                               }
+                                                               stmt->setTarget($2);
+                                                               stmt->setArgument($3);
+                                                               stmt->setIsHAB(false);
+                                                               if ($3)
+                                                               {
+                                                                       stmt->setLocation(@1, @3);
+                                                               }
+                                                               else
+                                                               {
+                                                                       stmt->setLocation(@1, @2);
+                                                               }
+                                                               $$ = stmt;
+                                                       }
+                               |               "hab" call_or_jump address_or_range call_arg_opt
+                                                       {
+                                                               if (!elftosb::g_enableHABSupport)
+                                                               {
+                                                                       yyerror(&yylloc, lexer, resultAST, "HAB features not supported with the selected family");
+                                                                       YYABORT;
+                                                               }
+                                                               
+                                                               CallStatementASTNode * stmt = new CallStatementASTNode();
+                                                               switch ($2)
+                                                               {
+                                                                       case 1:
+                                                                               stmt->setCallType(CallStatementASTNode::kCallType);
+                                                                               break;
+                                                                       case 2:
+                                                                               stmt->setCallType(CallStatementASTNode::kJumpType);
+                                                                               break;
+                                                                       default:
+                                                                               yyerror(&yylloc, lexer, resultAST, "invalid call_or_jump value");
+                                                                               YYABORT;
+                                                                               break;
+                                                               }
+                                                               stmt->setTarget($3);
+                                                               stmt->setArgument($4);
+                                                               stmt->setIsHAB(true);
+                                                               if ($4)
+                                                               {
+                                                                       stmt->setLocation(@1, @4);
+                                                               }
+                                                               else
+                                                               {
+                                                                       stmt->setLocation(@1, @3);
+                                                               }
+                                                               $$ = stmt;
+                                                       }
+                               ;
+
+call_or_jump   :               "call"          { $$ = 1; }
+                               |               "jump"          { $$ = 2; }
+                               ;
+
+call_target            :               TOK_SOURCE_NAME
+                                                       {
+                                                               $$ = new SymbolASTNode(NULL, $1);
+                                                               $$->setLocation(@1);
+                                                       }
+                               |               int_const_expr
+                                                       {
+                                                               $$ = new AddressRangeASTNode($1, NULL);
+                                                               $$->setLocation($1);
+                                                       }
+                               ;
+
+call_arg_opt   :               '(' int_const_expr ')'          { $$ = $2; }
+                               |               '(' ')'                                         { $$ = NULL; }
+                               |               /* empty */                                     { $$ = NULL; }
+                               ;
+
+from_stmt              :               "from" TOK_SOURCE_NAME '{' basic_stmt_list '}'
+                                                       {
+                                                               $$ = new FromStatementASTNode($2, dynamic_cast<ListASTNode*>($4));
+                                                               $$->setLocation(@1, @5);
+                                                       }
+                               ;
+
+mode_stmt              :               "mode" int_const_expr
+                                                       {
+                                                               $$ = new ModeStatementASTNode(dynamic_cast<ExprASTNode*>($2));
+                                                               $$->setLocation(@1, @2);
+                                                       }
+                               ;
+
+message_stmt   :               "info" TOK_STRING_LITERAL
+                                                       {
+                                                               $$ = new MessageStatementASTNode(MessageStatementASTNode::kInfo, $2);
+                                                               $$->setLocation(@1, @2);
+                                                       }
+                               |               "warning" TOK_STRING_LITERAL
+                                                       {
+                                                               $$ = new MessageStatementASTNode(MessageStatementASTNode::kWarning, $2);
+                                                               $$->setLocation(@1, @2);
+                                                       }
+                               |               "error" TOK_STRING_LITERAL
+                                                       {
+                                                               $$ = new MessageStatementASTNode(MessageStatementASTNode::kError, $2);
+                                                               $$->setLocation(@1, @2);
+                                                       }
+                               ;
+
+if_stmt                        :               "if" bool_expr '{' full_stmt_list '}' else_opt
+                                                       {
+                                                               IfStatementASTNode * ifStmt = new IfStatementASTNode();
+                                                               ifStmt->setConditionExpr(dynamic_cast<ExprASTNode*>($2));
+                                                               ifStmt->setIfStatements(dynamic_cast<ListASTNode*>($4));
+                                                               ifStmt->setElseStatements(dynamic_cast<ListASTNode*>($6));
+                                                               ifStmt->setLocation(@1, @6);
+                                                               $$ = ifStmt;
+                                                       }
+                               ;
+
+else_opt               :               "else" '{' full_stmt_list '}'
+                                                       {
+                                                               $$ = $3;
+                                                       }
+                               |               "else" if_stmt
+                                                       {
+                                                               ListASTNode * list = new ListASTNode();
+                                                               list->appendNode($2);
+                                                               $$ = list;
+                                                               $$->setLocation(@1, @2);
+                                                       }
+                               |               /* empty */                     { $$ = NULL; }
+                               ;
+
+address_or_range       :       int_const_expr
+                                                       {
+                                                               $$ = new AddressRangeASTNode($1, NULL);
+                                                               $$->setLocation($1);
+                                                       }
+                                       |       int_const_expr ".." int_const_expr
+                                                       {
+                                                               $$ = new AddressRangeASTNode($1, $3);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                                       ;
+
+const_expr             :       bool_expr
+                                                       {
+                                                               $$ = $1;
+                                                       }
+                               |       TOK_STRING_LITERAL
+                                                       {
+                                                               $$ = new StringConstASTNode($1);
+                                                               $$->setLocation(@1);
+                                                       }
+                               ;
+
+bool_expr              :       int_const_expr
+                                               {
+                                                       $$ = $1;
+                                               }
+                               |       bool_expr '<' bool_expr
+                                               {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                       $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kLessThan, right);
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       bool_expr '>' bool_expr
+                                               {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                       $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kGreaterThan, right);
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       bool_expr ">=" bool_expr
+                                               {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                       $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kGreaterThanEqual, right);
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       bool_expr "<=" bool_expr
+                                               {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                       $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kLessThanEqual, right);
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       bool_expr "==" bool_expr
+                                               {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                       $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kEqual, right);
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       bool_expr "!=" bool_expr
+                                               {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                       $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kNotEqual, right);
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       bool_expr "&&" bool_expr
+                                               {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                       $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBooleanAnd, right);
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       bool_expr "||" bool_expr
+                                               {
+                                                       ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                       ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                       $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBooleanOr, right);
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       '!' bool_expr %prec UNARY_OP
+                                               {
+                                                       $$ = new BooleanNotExprASTNode(dynamic_cast<ExprASTNode*>($2));
+                                                       $$->setLocation(@1, @2);
+                                               }
+                               |       TOK_IDENT '(' TOK_SOURCE_NAME ')'
+                                               {
+                                                       $$ = new SourceFileFunctionASTNode($1, $3);
+                                                       $$->setLocation(@1, @4);
+                                               }
+                               |       '(' bool_expr ')'
+                                               {
+                                                       $$ = $2;
+                                                       $$->setLocation(@1, @3);
+                                               }
+                               |       "defined" '(' TOK_IDENT ')'
+                                               {
+                                                       $$ = new DefinedOperatorASTNode($3);
+                                                       $$->setLocation(@1, @4);
+                                               }
+                               ;
+
+int_const_expr :       expr                            { $$ = $1; }
+                               ;
+
+symbol_ref             :       TOK_SOURCE_NAME ':' TOK_IDENT
+                                                       {
+                                                               $$ = new SymbolASTNode($3, $1);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |       ':' TOK_IDENT
+                                                       {
+                                                               $$ = new SymbolASTNode($2);
+                                                               $$->setLocation(@1, @2);
+                                                       }
+                               ;
+
+
+expr                   :               int_value
+                                                       {
+                                                               $$ = $1;
+                                                       }
+                               |               TOK_IDENT
+                                                       {
+                                                               $$ = new VariableExprASTNode($1);
+                                                               $$->setLocation(@1);
+                                                       }
+                               |               symbol_ref
+                                                       {
+                                                               $$ = new SymbolRefExprASTNode(dynamic_cast<SymbolASTNode*>($1));
+                                                               $$->setLocation(@1);
+                                                       }
+/*                             |               expr '..' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new RangeExprASTNode(left, right);
+                                                       }
+*/                             |               expr '+' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kAdd, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr '-' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kSubtract, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr '*' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kMultiply, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr '/' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kDivide, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr '%' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kModulus, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr "**" expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kPower, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr '&' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseAnd, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr '|' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseOr, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr '^' expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kBitwiseXor, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr "<<" expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kShiftLeft, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               expr ">>" expr
+                                                       {
+                                                               ExprASTNode * left = dynamic_cast<ExprASTNode*>($1);
+                                                               ExprASTNode * right = dynamic_cast<ExprASTNode*>($3);
+                                                               $$ = new BinaryOpExprASTNode(left, BinaryOpExprASTNode::kShiftRight, right);
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               unary_expr
+                                                       {
+                                                               $$ = $1;
+                                                       }
+                               |               expr '.' TOK_INT_SIZE   
+                                                       {
+                                                               $$ = new IntSizeExprASTNode(dynamic_cast<ExprASTNode*>($1), $3->getWordSize());
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |               '(' expr ')'
+                                                       {
+                                                               $$ = $2;
+                                                               $$->setLocation(@1, @3);
+                                                       }
+                               |       "sizeof" '(' symbol_ref ')'
+                                               {
+                                                       $$ = new SizeofOperatorASTNode(dynamic_cast<SymbolASTNode*>($3));
+                                                       $$->setLocation(@1, @4);
+                                               }
+                               |       "sizeof" '(' TOK_IDENT ')'
+                                               {
+                                                       $$ = new SizeofOperatorASTNode($3);
+                                                       $$->setLocation(@1, @4);
+                                               }
+                               |       "sizeof" '(' TOK_SOURCE_NAME ')'
+                                               {
+                                                       $$ = new SizeofOperatorASTNode($3);
+                                                       $$->setLocation(@1, @4);
+                                               }
+                               ;
+
+unary_expr             :               '+' expr %prec UNARY_OP
+                                                       {
+                                                               $$ = $2;
+                                                       }
+                               |               '-' expr %prec UNARY_OP
+                                                       {
+                                                               $$ = new NegativeExprASTNode(dynamic_cast<ExprASTNode*>($2));
+                                                               $$->setLocation(@1, @2);
+                                                       }
+                               ;
+
+int_value              :               TOK_INT_LITERAL
+                                                       {
+                                                               $$ = new IntConstExprASTNode($1->getValue(), $1->getWordSize());
+                                                               $$->setLocation(@1);
+                                                       }
+                               ;
+
+%%
+
+/* code goes here */
+
+static int yylex(YYSTYPE * lvalp, YYLTYPE * yylloc, ElftosbLexer * lexer)
+{
+       int token = lexer->yylex();
+       *yylloc = lexer->getLocation();
+       lexer->getSymbolValue(lvalp);
+       return token;
+}
+
+static void yyerror(YYLTYPE * yylloc, ElftosbLexer * lexer, CommandFileASTNode ** resultAST, const char * error)
+{
+       throw syntax_error(format_string("line %d: %s\n", yylloc->m_firstLine, error));
+}
+
diff --git a/tools/elftosb/encryptgpk/encryptgpk.cpp b/tools/elftosb/encryptgpk/encryptgpk.cpp
new file mode 100644 (file)
index 0000000..e389fef
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ * File:       encryptgpk.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "stdafx.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <stdlib.h>
+#include <stdexcept>
+#include <stdio.h>
+#include "options.h"
+#include "EncoreBootImage.h"
+#include "smart_ptr.h"
+#include "Logging.h"
+#include "format_string.h"
+#include "Blob.h"
+#include "Random.h"
+#include "rijndael.h"
+
+using namespace elftosb;
+
+//! Size in bytes of the unencrypted group private key.
+#define GPK_LENGTH (40)
+
+//! Size in bytes of the encrypted output data. This size must be modulo 16, the chunk size for the
+//! AES-128 crypto algorithm. The group private key is inserted at offset 16.
+#define OUTPUT_DATA_LENGTH (64)
+
+//! Position in the output data of the first byte of the group private key.
+#define OUTPUT_DATA_GPK_OFFSET (16)
+
+//! The tool's name.
+const char k_toolName[] = "encryptgpk";
+
+//! Current version number for the tool.
+const char k_version[] = "1.0.2";
+
+//! Copyright string.
+const char k_copyright[] = "Copyright (c) 2008 Freescale Semiconductor. All rights reserved.";
+
+//! Default output array name.
+const char k_defaultArrayName[] = "_endDisplay";
+
+//! Definition of command line options.
+static const char * k_optionsDefinition[] = {
+       "?|help",
+       "v|version",
+       "k:key <file>",
+       "z|zero-key",
+       "o:output",
+       "p:prefix",
+       "a:array",
+       "d|debug",
+       "q|quiet",
+       "V|verbose",
+       NULL
+};
+
+//! Help string.
+const char k_usageText[] = "\nOptions:\n\
+  -?/--help                    Show this help\n\
+  -v/--version                 Display tool version\n\
+  -k/--key <file>              Add OTP key used for decryption\n\
+  -z/--zero-key                Add default key of all zeroes\n\
+  -o/--output <file>           Write output to this file\n\
+  -p/--prefix <prefix>         Set the output array prefix\n\
+  -a/--array <name>            Specify the output array name\n\
+  -d/--debug                   Enable debug output\n\
+  -q/--quiet                   Output only warnings and errors\n\
+  -V/--verbose                 Print extra detailed log information\n\n";
+
+//! Init vector used for CBC encrypting the output data.
+static const uint8_t kInitVector[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+
+//! An array of strings.
+typedef std::vector<std::string> string_vector_t;
+
+// prototypes
+int main(int argc, char* argv[], char* envp[]);
+
+/*!
+ * \brief Class that encapsulates the sbtool interface.
+ *
+ * A single global logger instance is created during object construction. It is
+ * never freed because we need it up to the last possible minute, when an
+ * exception could be thrown.
+ */
+class encryptgpk
+{
+protected:
+       int m_argc;                                                     //!< Number of command line arguments.
+       char ** m_argv;                                         //!< String value for each command line argument.
+       StdoutLogger * m_logger;                        //!< Singleton logger instance.
+       string_vector_t m_keyFilePaths;         //!< Paths to OTP key files.
+       string_vector_t m_positionalArgs;       //!< Arguments coming after explicit options.
+       bool m_isVerbose;                                       //!< Whether the verbose flag was turned on.
+       bool m_useDefaultKey;                                   //!< Include a default (zero) crypto key.
+       std::string m_outputPath;                       //!< Path to output file.
+       std::string m_gpkPath;                          //!< Path to input group private key file.
+       std::string m_outputPrefix;                     //!< Prefix to the output array.
+       std::string m_arrayName;                        //!< Output array's name.
+       
+public:
+       /*!
+        * Constructor.
+        *
+        * Creates the singleton logger instance.
+        */
+       encryptgpk(int argc, char * argv[])
+       :       m_argc(argc),
+               m_argv(argv),
+               m_logger(0),
+               m_keyFilePaths(),
+               m_positionalArgs(),
+               m_isVerbose(false),
+               m_useDefaultKey(false),
+               m_outputPath(),
+               m_gpkPath(),
+               m_outputPrefix(),
+               m_arrayName(k_defaultArrayName)
+       {
+               // create logger instance
+               m_logger = new StdoutLogger();
+               m_logger->setFilterLevel(Logger::INFO);
+               Log::setLogger(m_logger);
+       }
+       
+       /*!
+        * Destructor.
+        */
+       ~encryptgpk()
+       {
+       }
+       
+       /*!
+        * Reads the command line options passed into the constructor.
+        *
+        * This method can return a return code to its caller, which will cause the
+        * tool to exit immediately with that return code value. Normally, though, it
+        * will return -1 to signal that the tool should continue to execute and
+        * all options were processed successfully.
+        *
+        * The Options class is used to parse command line options. See
+        * #k_optionsDefinition for the list of options and #k_usageText for the
+        * descriptive help for each option.
+        *
+        * \retval -1 The options were processed successfully. Let the tool run normally.
+        * \return A zero or positive result is a return code value that should be
+        *              returned from the tool as it exits immediately.
+        */
+       int processOptions()
+       {
+               Options options(*m_argv, k_optionsDefinition);
+               OptArgvIter iter(--m_argc, ++m_argv);
+               
+               // process command line options
+               int optchar;
+               const char * optarg;
+               while (optchar = options(iter, optarg))
+               {
+                       switch (optchar)
+                       {
+                               case '?':
+                                       printUsage(options);
+                                       return 0;
+                               
+                               case 'v':
+                                       printf("%s %s\n%s\n", k_toolName, k_version, k_copyright);
+                                       return 0;
+                                       
+                               case 'k':
+                                       m_keyFilePaths.push_back(optarg);
+                                       break;
+                               
+                               case 'z':
+                                       m_useDefaultKey = true;
+                                       break;
+                               
+                               case 'o':
+                                       m_outputPath = optarg;
+                                       break;
+
+                               case 'p':
+                                       m_outputPrefix = optarg;
+                                       break;
+
+                               case 'a':
+                                       m_arrayName = optarg;
+                                       break;
+                               
+                               case 'd':
+                                       Log::getLogger()->setFilterLevel(Logger::DEBUG);
+                                       break;
+                                       
+                               case 'q':
+                                       Log::getLogger()->setFilterLevel(Logger::WARNING);
+                                       break;
+                                       
+                               case 'V':
+                                       m_isVerbose = true;
+                                       break;
+                               
+                               default:
+                                       Log::log(Logger::ERROR, "error: unrecognized option\n\n");
+                                       printUsage(options);
+                                       return 1;
+                       }
+               }
+               
+               // handle positional args
+               if (iter.index() < m_argc)
+               {
+//                     Log::SetOutputLevel leveler(Logger::DEBUG);
+//                     Log::log("positional args:\n");
+                       int i;
+                       for (i = iter.index(); i < m_argc; ++i)
+                       {
+//                             Log::log("%d: %s\n", i - iter.index(), m_argv[i]);
+                               m_positionalArgs.push_back(m_argv[i]);
+                       }
+               }
+               
+               // all is well
+               return -1;
+       }
+
+       /*!
+        * Prints help for the tool.
+        */
+       void printUsage(Options & options)
+       {
+               options.usage(std::cout, "gpk-file");
+               printf(k_usageText, k_toolName);
+       }
+       
+       /*!
+        * Core of the tool. Calls processOptions() to handle command line options
+        * before performing the real work the tool does.
+        */
+       int run()
+       {
+               try
+               {
+                       // read command line options
+                       int result;
+                       if ((result = processOptions()) != -1)
+                       {
+                               return result;
+                       }
+                       
+                       // set verbose logging
+                       setVerboseLogging();
+                       
+                       // make sure a file was provided
+                       if (m_positionalArgs.size() < 1)
+                       {
+                               throw std::runtime_error("no input file path was provided");
+                       }
+
+                       // Make sure at least one key was specified.
+                       if (m_keyFilePaths.size() == 0 && m_useDefaultKey == false)
+                       {
+                               throw std::runtime_error("no crypto key was specified");
+                       }
+                       
+                       // Do the work.
+                       generateOutput();
+               }
+               catch (std::exception & e)
+               {
+                       Log::log(Logger::ERROR, "error: %s\n", e.what());
+                       return 1;
+               }
+               catch (...)
+               {
+                       Log::log(Logger::ERROR, "error: unexpected exception\n");
+                       return 1;
+               }
+               
+               return 0;
+       }
+
+       /*!
+        * \brief Builds the output data blob, encrypts it, and writes it to the output file.
+        */
+       void generateOutput()
+       {
+               // Create the output data blob and set it to the correct size.
+               Blob data;
+               data.setLength(OUTPUT_DATA_LENGTH);
+               
+               // Fill it with random values.
+               RandomNumberGenerator rng;
+               rng.generateBlock(data.getData(), OUTPUT_DATA_LENGTH);
+
+               // Read the GPK and overlay it into the output data.
+               // The first positional arg is the GPK file path.
+               Blob gpk = readGPK(m_positionalArgs[0]);
+               memcpy(data.getData() + OUTPUT_DATA_GPK_OFFSET, gpk.getData(), GPK_LENGTH);
+
+               // This is the key object for our crypto key.
+               AESKey<128> cryptoKey = readKeyFile();
+
+               // Read the key file.
+               // Encrypt the output data block.
+               Rijndael cipher;
+               cipher.init(Rijndael::CBC, Rijndael::Encrypt, cryptoKey, Rijndael::Key16Bytes, (uint8_t *)&kInitVector);
+               cipher.blockEncrypt(data.getData(), OUTPUT_DATA_LENGTH * 8, data.getData());
+
+               // Open the output file.
+               std::ofstream outputStream(m_outputPath.c_str(), std::ios_base::out | std::ios_base::trunc);
+               if (!outputStream.is_open())
+               {
+                       throw std::runtime_error(format_string("could not open output file %s", m_outputPath.c_str()));
+               }
+               
+               writeCArray(outputStream, data);
+       }
+
+       /*!
+        * \brief Reads the group private key binary data.
+        */
+       Blob readGPK(std::string & path)
+       {
+               std::ifstream stream(path.c_str(), std::ios_base::in | std::ios_base::binary);
+               if (!stream.is_open())
+               {
+                       throw std::runtime_error("could not open group private key file");
+               }
+
+               Blob gpk;
+               gpk.setLength(GPK_LENGTH);
+
+               stream.read((char *)gpk.getData(), GPK_LENGTH);
+
+               return gpk;
+       }
+
+       /*!
+        * \brief Returns a key object based on the user's specified key.
+        */
+       AESKey<128> readKeyFile()
+       {
+               if (m_keyFilePaths.size() > 0)
+               {
+                       // Open the key file.
+                       std::string & keyPath = m_keyFilePaths[0];
+                       std::ifstream keyStream(keyPath.c_str(), std::ios_base::in);
+                       if (!keyStream.is_open())
+                       {
+                               throw std::runtime_error(format_string("unable to read key file %s\n", keyPath.c_str()));
+                       }
+                       keyStream.seekg(0);
+                       
+                       // Read the first key in the file.
+                       AESKey<128> key(keyStream);
+                       return key;
+               }
+
+               // Otherwise, create a zero key and return it.
+               AESKey<128> defaultKey;
+               return defaultKey;
+
+       }
+
+       /*!
+        * \brief Writes the given data blob as an array in a C source file.
+        */
+       void writeCArray(std::ofstream & stream, const Blob & data)
+       {
+               const uint8_t * dataPtr = data.getData();
+               unsigned length = data.getLength();
+
+               // Write first line.
+               std::string text = format_string("%s%sunsigned char %s[%d] = {", m_outputPrefix.c_str(), m_outputPrefix.size() > 0 ? " " : "", m_arrayName.c_str(), length);
+               stream.write(text.c_str(), text.size());
+               
+               // Write each word of the array.
+               unsigned i = 0;
+               while (i < length)
+               {
+                       // Insert a comma at the end of the previous line unless this is the first word we're outputting.
+                       text = format_string("%s\n    0x%02x", i == 0 ? "" : ",", (*dataPtr++) & 0xff);
+                       stream.write(text.c_str(), text.size());
+
+                       i++;
+               }
+
+               // Write last line, terminating the array.
+               text = "\n};\n\n";
+               stream.write(text.c_str(), text.size());
+       }
+       
+       /*!
+        * \brief Turns on verbose logging.
+        */
+       void setVerboseLogging()
+       {
+               if (m_isVerbose)
+               {
+                       // verbose only affects the INFO and DEBUG filter levels
+                       // if the user has selected quiet mode, it overrides verbose
+                       switch (Log::getLogger()->getFilterLevel())
+                       {
+                               case Logger::INFO:
+                                       Log::getLogger()->setFilterLevel(Logger::INFO2);
+                                       break;
+                               case Logger::DEBUG:
+                                       Log::getLogger()->setFilterLevel(Logger::DEBUG2);
+                                       break;
+                       }
+               }
+       }
+
+};
+
+/*!
+ * Main application entry point. Creates an sbtool instance and lets it take over.
+ */
+int main(int argc, char* argv[], char* envp[])
+{
+       try
+       {
+               return encryptgpk(argc, argv).run();
+       }
+       catch (...)
+       {
+               Log::log(Logger::ERROR, "error: unexpected exception\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+
+
+
+
diff --git a/tools/elftosb/encryptgpk/encryptgpk.vcproj b/tools/elftosb/encryptgpk/encryptgpk.vcproj
new file mode 100644 (file)
index 0000000..8f5cd24
--- /dev/null
@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9.00"\r
+       Name="encryptgpk"\r
+       ProjectGUID="{5C28390B-78FC-4484-BBB5-E425F9852CCE}"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\winsupport;..\common"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/encryptgpk.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/encryptgpk.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalIncludeDirectories="..\winsupport;..\common"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
+                               RuntimeLibrary="0"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/encryptgpk.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\encryptgpk.cpp"\r
+                               >\r
+                       </File>\r
+                       <Filter\r
+                               Name="common"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\common\AESKey.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Blob.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\crc.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\format_string.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\HexValues.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Logging.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\options.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Random.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\rijndael.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\RijndaelCBCMAC.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SearchPath.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SHA1.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\stdafx.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Value.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Version.cpp"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+                       <Filter\r
+                               Name="common"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\common\AESKey.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Blob.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\BootImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\crc.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELF.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EndianUtilities.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\format_string.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\HexValues.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\int_size.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Logging.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\options.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Random.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\rijndael.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\RijndaelCBCMAC.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SearchPath.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SHA1.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\smart_ptr.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\stdafx.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Value.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Version.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/tools/elftosb/keygen/Doxyfile b/tools/elftosb/keygen/Doxyfile
new file mode 100644 (file)
index 0000000..0b20ed1
--- /dev/null
@@ -0,0 +1,250 @@
+# Doxyfile 1.3.9
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = sbtool
+PROJECT_NUMBER         = 1.0
+OUTPUT_DIRECTORY       = .
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = "/Users/creed/projects/elftosb/sbtool" \
+                                                "/Users/creed/projects/sgtl/elftosb/sbtool" \
+                                                "/Users/creed/projects/elftosb/common" \
+                                                "/Users/creed/projects/sgtl/elftosb/common"
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 4
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = NO
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = . ../common
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm
+RECURSIVE              = NO
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+VERBATIM_HEADERS       = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/tools/elftosb/keygen/keygen.cpp b/tools/elftosb/keygen/keygen.cpp
new file mode 100644 (file)
index 0000000..b1b8362
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * File:       keygen.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "stdafx.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <stdlib.h>
+#include <stdexcept>
+#include <string>
+#include <vector>
+#include "options.h"
+#include "smart_ptr.h"
+#include "Logging.h"
+#include "AESKey.h"
+
+//! The tool's name.
+const char k_toolName[] = "keygen";
+
+//! Current version number for the tool.
+const char k_version[] = "1.0";
+
+//! Copyright string.
+const char k_copyright[] = "Copyright (c) 2006-2009 Freescale Semiconductor, Inc.\nAll rights reserved.";
+
+//! Definition of command line options.
+static const char * k_optionsDefinition[] = {
+       "?|help",
+       "v|version",
+       "q|quiet",
+       "V|verbose",
+       "n:number <int>",
+       NULL
+};
+
+//! Help string.
+const char k_usageText[] = "\nOptions:\n\
+  -?/--help                    Show this help\n\
+  -v/--version                 Display tool version\n\
+  -q/--quiet                   Output only warnings and errors\n\
+  -V/--verbose                 Print extra detailed log information\n\
+  -n/--number <int>            Number of keys to generate per file (default=1)\n\n";
+
+//! An array of strings.
+typedef std::vector<std::string> string_vector_t;
+
+// prototypes
+int main(int argc, char* argv[], char* envp[]);
+
+/*!
+ * \brief Class that encapsulates the keygen interface.
+ *
+ * A single global logger instance is created during object construction. It is
+ * never freed because we need it up to the last possible minute, when an
+ * exception could be thrown.
+ */
+class keygen
+{
+protected:
+       int m_argc;                                                     //!< Number of command line arguments.
+       char ** m_argv;                                         //!< String value for each command line argument.
+       StdoutLogger * m_logger;                        //!< Singleton logger instance.
+       string_vector_t m_positionalArgs;       //!< Arguments coming after explicit options.
+       bool m_isVerbose;                                       //!< Whether the verbose flag was turned on.
+       int m_keyCount;                                         //!< Number of keys to generate.
+       
+public:
+       /*!
+        * Constructor.
+        *
+        * Creates the singleton logger instance.
+        */
+       keygen(int argc, char * argv[])
+       :       m_argc(argc),
+               m_argv(argv),
+               m_logger(0),
+               m_positionalArgs(),
+               m_isVerbose(false),
+               m_keyCount(1)
+       {
+               // create logger instance
+               m_logger = new StdoutLogger();
+               m_logger->setFilterLevel(Logger::INFO);
+               Log::setLogger(m_logger);
+       }
+       
+       /*!
+        * Destructor.
+        */
+       ~keygen()
+       {
+       }
+       
+       /*!
+        * Reads the command line options passed into the constructor.
+        *
+        * This method can return a return code to its caller, which will cause the
+        * tool to exit immediately with that return code value. Normally, though, it
+        * will return -1 to signal that the tool should continue to execute and
+        * all options were processed successfully.
+        *
+        * The Options class is used to parse command line options. See
+        * #k_optionsDefinition for the list of options and #k_usageText for the
+        * descriptive help for each option.
+        *
+        * \retval -1 The options were processed successfully. Let the tool run normally.
+        * \return A zero or positive result is a return code value that should be
+        *              returned from the tool as it exits immediately.
+        */
+       int processOptions()
+       {
+               Options options(*m_argv, k_optionsDefinition);
+               OptArgvIter iter(--m_argc, ++m_argv);
+               
+               // process command line options
+               int optchar;
+               const char * optarg;
+               while (optchar = options(iter, optarg))
+               {
+                       switch (optchar)
+                       {
+                               case '?':
+                                       printUsage(options);
+                                       return 0;
+                               
+                               case 'v':
+                                       printf("%s %s\n%s\n", k_toolName, k_version, k_copyright);
+                                       return 0;
+                                       
+                               case 'd':
+                                       Log::getLogger()->setFilterLevel(Logger::DEBUG);
+                                       break;
+                                       
+                               case 'q':
+                                       Log::getLogger()->setFilterLevel(Logger::WARNING);
+                                       break;
+                                       
+                               case 'V':
+                                       m_isVerbose = true;
+                                       break;
+                               
+                               case 'n':
+                                       m_keyCount = strtol(optarg, NULL, 0);
+                                       break;
+                               
+                               default:
+                                       Log::log(Logger::ERROR, "error: unrecognized option\n\n");
+                                       printUsage(options);
+                                       return 1;
+                       }
+               }
+               
+               // handle positional args
+               if (iter.index() < m_argc)
+               {
+//                     Log::SetOutputLevel leveler(Logger::DEBUG);
+//                     Log::log("positional args:\n");
+                       int i;
+                       for (i = iter.index(); i < m_argc; ++i)
+                       {
+//                             Log::log("%d: %s\n", i - iter.index(), m_argv[i]);
+                               m_positionalArgs.push_back(m_argv[i]);
+                       }
+               }
+               
+               // all is well
+               return -1;
+       }
+
+       /*!
+        * Prints help for the tool.
+        */
+       void printUsage(Options & options)
+       {
+               options.usage(std::cout, "key-files...");
+               printf(k_usageText, k_toolName);
+       }
+       
+       /*!
+        * Core of the tool. Calls processOptions() to handle command line options
+        * before performing the real work the tool does.
+        */
+       int run()
+       {
+               try
+               {
+                       // read command line options
+                       int result;
+                       if ((result = processOptions()) != -1)
+                       {
+                               return result;
+                       }
+                       
+                       // set verbose logging
+                       setVerboseLogging();
+                       
+                       // make sure a file was provided
+                       if (m_positionalArgs.size() < 1)
+                       {
+                               throw std::runtime_error("no output file path was provided");
+                       }
+                       
+                       // generate key files
+                       string_vector_t::const_iterator it = m_positionalArgs.begin();
+                       for (; it != m_positionalArgs.end(); ++it)
+                       {
+                               generateKeyFile(*it);
+                       }
+               }
+               catch (std::exception & e)
+               {
+                       Log::log(Logger::ERROR, "error: %s\n", e.what());
+                       return 1;
+               }
+               catch (...)
+               {
+                       Log::log(Logger::ERROR, "error: unexpected exception\n");
+                       return 1;
+               }
+               
+               return 0;
+       }
+       
+       /*!
+        * \brief Turns on verbose logging.
+        */
+       void setVerboseLogging()
+       {
+               if (m_isVerbose)
+               {
+                       // verbose only affects the INFO and DEBUG filter levels
+                       // if the user has selected quiet mode, it overrides verbose
+                       switch (Log::getLogger()->getFilterLevel())
+                       {
+                               case Logger::INFO:
+                                       Log::getLogger()->setFilterLevel(Logger::INFO2);
+                                       break;
+                               case Logger::DEBUG:
+                                       Log::getLogger()->setFilterLevel(Logger::DEBUG2);
+                                       break;
+                       }
+               }
+       }
+       
+       /*!
+        * \brief Opens the file at \a path and writes a random key file.
+        *
+        * Each key file will have #m_keyCount number of keys written into it,
+        * each on a line by itself.
+        */
+       void generateKeyFile(const std::string & path)
+       {
+               std::ofstream outputStream(path.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
+               if (outputStream.is_open())
+               {
+                       int i;
+                       for (i = 0; i < m_keyCount; ++i)
+                       {
+                               AESKey<128> key;
+                               key.randomize();
+                               key.writeToStream(outputStream);
+                               
+                               // put a newline after the key
+                               outputStream.write("\n", 1);
+                               
+                               // dump it
+                               dumpKey(key);
+                       }
+                       
+                       Log::log(Logger::INFO, "wrote key file %s\n", path.c_str());
+               }
+               else
+               {
+                       throw std::runtime_error("could not open output file");
+               }
+       }
+       
+       /*!
+        * \brief Write the value of each byte of the \a key to the log.
+        */
+       void dumpKey(const AESKey<128> & key)
+       {
+               // dump key bytes
+               Log::log(Logger::INFO2, "key bytes: ");
+               AESKey<128>::key_t the_key;
+               key.getKey(&the_key);
+               int q;
+               for (q=0; q<16; q++)
+               {
+                       Log::log(Logger::INFO2, "%02x ", the_key[q]);
+               }
+               Log::log(Logger::INFO2, "\n");
+       }
+       
+       /*!
+        * \brief Log an array of bytes as hex.
+        */
+       void logHexArray(Logger::log_level_t level, const uint8_t * bytes, unsigned count)
+       {
+               Log::SetOutputLevel leveler(level);
+//             Log::log("    ");
+               unsigned i;
+               for (i = 0; i < count; ++i, ++bytes)
+               {
+                       if ((i % 16 == 0) && (i < count - 1))
+                       {
+                               if (i != 0)
+                               {
+                                       Log::log("\n");
+                               }
+                               Log::log("    0x%04x: ", i);
+                       }
+                       Log::log("%02x ", *bytes & 0xff);
+               }
+               
+               Log::log("\n");
+       }
+
+};
+
+/*!
+ * Main application entry point. Creates an sbtool instance and lets it take over.
+ */
+int main(int argc, char* argv[], char* envp[])
+{
+       try
+       {
+               return keygen(argc, argv).run();
+       }
+       catch (...)
+       {
+               Log::log(Logger::ERROR, "error: unexpected exception\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+
+
+
+
diff --git a/tools/elftosb/keygen/keygen.vcproj b/tools/elftosb/keygen/keygen.vcproj
new file mode 100644 (file)
index 0000000..eda4af3
--- /dev/null
@@ -0,0 +1,478 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9.00"\r
+       Name="keygen"\r
+       ProjectGUID="{09633A11-9AB3-4118-B83A-5D6CAFDBE74F}"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\winsupport;..\elftosb2;..\common"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               RuntimeTypeInfo="true"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="2"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                               DisableSpecificWarnings="4355"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/keygen.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/keygen.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
+                               RuntimeLibrary="0"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/keygen.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <Filter\r
+                               Name="keygen"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\keygen.cpp"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="common"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\common\AESKey.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\AESKey.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Blob.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Blob.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\BootImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\crc.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\crc.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataSource.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataSource.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataTarget.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataTarget.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELF.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELFSourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELFSourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EncoreBootImage.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EncoreBootImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EndianUtilities.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EvalContext.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EvalContext.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\format_string.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\format_string.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GHSSecInfo.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GHSSecInfo.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GlobMatcher.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GlobMatcher.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\HexValues.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\HexValues.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\int_size.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Logging.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Logging.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Operation.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Operation.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionContext.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionDictionary.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionDictionary.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\options.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\options.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OutputSection.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OutputSection.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Random.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Random.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\rijndael.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\rijndael.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\RijndaelCBCMAC.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\RijndaelCBCMAC.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SearchPath.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SearchPath.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SHA1.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SHA1.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\smart_ptr.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SRecordSourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SRecordSourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\stdafx.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\stdafx.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StELFFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StELFFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StExecutableImage.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StExecutableImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StringMatcher.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StSRecordFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StSRecordFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Value.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Value.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Version.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Version.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/tools/elftosb/makefile b/tools/elftosb/makefile
new file mode 100644 (file)
index 0000000..a98e71b
--- /dev/null
@@ -0,0 +1,32 @@
+#*******************************************************************************
+#                               makefile
+# Description:
+#   gnu make makefile for elftosb executable
+#*******************************************************************************
+#                               Environment
+
+# UNAMES is going to be set to either "Linux" or "CYGWIN_NT-5.1"
+UNAMES = $(shell uname -s)
+
+ifeq ("${UNAMES}", "Linux")
+
+SRC_DIR = $(shell pwd)
+BUILD_DIR = bld/linux
+
+else 
+ifeq ("${UNAMES}", "CYGWIN_NT-5.1")
+
+SRC_DIR = $(shell pwd)
+BUILD_DIR = bld/cygwin
+
+endif
+endif
+
+
+#*******************************************************************************
+#                                 Targets
+
+all clean elftosb sbtool keygen:
+       @mkdir -p ${BUILD_DIR};
+       make -C ${BUILD_DIR} -f ${SRC_DIR}/makefile.rules SRC_DIR=${SRC_DIR} $@;
diff --git a/tools/elftosb/makefile.rules b/tools/elftosb/makefile.rules
new file mode 100644 (file)
index 0000000..9cd649e
--- /dev/null
@@ -0,0 +1,178 @@
+#*******************************************************************************
+#                               makefile.rules
+# Description:
+#   gnu make makefile rules for elftosb executable.  make needs to be called
+#   with the following command:
+#
+#   make -C ${BUILD_DIR} -f ${SRC_DIR}/makefile.rules SRC_DIR=${SRC_DIR} $@;
+#
+#   SRC_DIR needs to be passed in.  It is assumed that make is running in
+#   the build directory.
+
+#*******************************************************************************
+#                               Environment
+
+# UNAMES is going to be set to either "Linux" or "CYGWIN_NT-5.1"
+UNAMES = $(shell uname -s)
+
+#*******************************************************************************
+#                               Directories
+
+#*******************************************************************************
+#                               Paths
+
+# search path for source files. make finds them automatically.
+VPATH = \
+       ${SRC_DIR}/common       \
+       ${SRC_DIR}/elftosb2 \
+       ${SRC_DIR}/sbtool       \
+       ${SRC_DIR}/keygen
+
+# include directories
+INC_PATH =                      \
+    -I${SRC_DIR}/elftosb2        \
+    -I${SRC_DIR}/keygen   \
+    -I${SRC_DIR}/sbtool      \
+       -I${SRC_DIR}/common
+
+#*******************************************************************************
+#                               Build flags
+# gcc Compiler flags
+#    -g                                                : Produce debugging information.
+
+CFLAGS     = -g $(INC_PATH) -D${UNAMES}
+
+#*******************************************************************************
+#                               File lists
+
+OBJ_FILES_COMMON =                     \
+       AESKey.o        \
+       Blob.o  \
+       crc.o   \
+       DataSource.o    \
+       DataTarget.o    \
+       ELFSourceFile.o \
+       EncoreBootImage.o       \
+       EvalContext.o   \
+       GHSSecInfo.o    \
+       GlobMatcher.o   \
+       HexValues.o \
+       Logging.o       \
+       Operation.o \
+       OptionDictionary.o      \
+       options.o       \
+       OutputSection.o \
+       Random.o        \
+       RijndaelCBCMAC.o        \
+       rijndael.o      \
+       SHA1.o  \
+       SourceFile.o    \
+       SRecordSourceFile.o \
+       stdafx.o        \
+       StELFFile.o \
+       StExecutableImage.o \
+       StSRecordFile.o \
+       Value.o \
+       Version.o \
+       format_string.o \
+       ExcludesListMatcher.o \
+       SearchPath.o    \
+       DataSourceImager.o \
+       IVTDataSource.o
+
+OBJ_FILES_ELFTOSB2 =           \
+       ${OBJ_FILES_COMMON} \
+       BootImageGenerator.o    \
+       ConversionController.o  \
+       ElftosbAST.o    \
+       elftosb.o       \
+       elftosb_lexer.o \
+       ElftosbLexer.o  \
+       elftosb_parser.tab.o    \
+       EncoreBootImageGenerator.o
+
+OBJ_FILES_SBTOOL =                     \
+       ${OBJ_FILES_COMMON} \
+       EncoreBootImageReader.o \
+       sbtool.o
+
+OBJ_FILES_KEYGEN =                     \
+       ${OBJ_FILES_COMMON} \
+       keygen.o
+
+
+LIBS =     -lstdc++
+
+
+ifeq ("${UNAMES}", "Linux")
+EXEC_FILE_ELFTOSB2 = elftosb
+EXEC_FILE_SBTOOL = sbtool
+EXEC_FILE_KEYGEN = keygen
+else 
+ifeq ("${UNAMES}", "CYGWIN_NT-5.1")
+EXEC_FILE_ELFTOSB2 = elftosb.exe
+EXEC_FILE_SBTOOL = sbtool.exe
+EXEC_FILE_KEYGEN = keygen.exe
+endif # ifeq ("${UNAMES}", "CYGWIN_NT-5.1")
+endif # ifeq ("${UNAMES}", "Linux")
+
+
+#*******************************************************************************
+#                                 Targets
+
+all: elftosb sbtool keygen
+
+# Uncomment the next line to print out the environment variables.
+all: exec_always
+
+exec_always:
+       @echo "SRC_DIR = ${SRC_DIR}"
+       @echo "OBJ_FILES = ${OBJ_FILES_ELFTOSB2}"
+       @echo "LIBS = ${LIBS}"
+       @echo "EXEC_FILE = ${EXEC_FILE}"
+       @echo "BUILD_DIR = ${BUILD_DIR}"
+
+clean:
+       rm -f ${OBJ_FILES_ELFTOSB2} ${OBJ_FILES_SBTOOL} ${OBJ_FILES_KEYGEN} \
+               ${EXEC_FILE_ELFTOSB2} ${EXEC_FILE_SBTOOL} ${EXEC_FILE_KEYGEN}
+
+elftosb: ${OBJ_FILES_ELFTOSB2}
+       gcc ${OBJ_FILES_ELFTOSB2} ${LIBS} -o ${EXEC_FILE_ELFTOSB2}
+
+sbtool: ${OBJ_FILES_SBTOOL}
+       gcc ${OBJ_FILES_SBTOOL} ${LIBS} -o ${EXEC_FILE_SBTOOL}
+
+keygen: ${OBJ_FILES_KEYGEN}
+       gcc ${OBJ_FILES_KEYGEN} ${LIBS} -o ${EXEC_FILE_KEYGEN}
+
+
+#ifeq ("${UNAMES}", "Linux")
+#ifeq ("${UNAMES}", "Linux")
+# Use default rules for creating all the .o files from the .c files.  Only
+# for linux
+.SUFFIXES : .c .cpp
+
+.c.o :
+       gcc ${CFLAGS} -c $<
+
+.cpp.o :
+       gcc ${CFLAGS} -c $<
+
+#endif
+
+#*******************************************************************************
+#                       Automatic dependency generation
+
+%.d: %.c
+       @set -e; \
+       $(CC) -MM $(CFLAGS) $< | \
+       sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
+       [ -s $@ ]  || rm -f $@
+
+%.d: %.cpp
+       @set -e; \
+       $(CC) -MM $(CFLAGS) $< | \
+       sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
+       [ -s $@ ]  || rm -f $@
+
+#*******************************************************************************
diff --git a/tools/elftosb/sbtool/Doxyfile b/tools/elftosb/sbtool/Doxyfile
new file mode 100644 (file)
index 0000000..0b20ed1
--- /dev/null
@@ -0,0 +1,250 @@
+# Doxyfile 1.3.9
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = sbtool
+PROJECT_NUMBER         = 1.0
+OUTPUT_DIRECTORY       = .
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = "/Users/creed/projects/elftosb/sbtool" \
+                                                "/Users/creed/projects/sgtl/elftosb/sbtool" \
+                                                "/Users/creed/projects/elftosb/common" \
+                                                "/Users/creed/projects/sgtl/elftosb/common"
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 4
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = NO
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = . ../common
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm
+RECURSIVE              = NO
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = *
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION    = NO
+VERBATIM_HEADERS       = NO
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = YES
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/tools/elftosb/sbtool/EncoreBootImageReader.cpp b/tools/elftosb/sbtool/EncoreBootImageReader.cpp
new file mode 100644 (file)
index 0000000..b6eb474
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * File:       EncoreBootImageReader.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "EncoreBootImageReader.h"
+#include "SHA1.h"
+#include "rijndael.h"
+#include "RijndaelCBCMAC.h"
+#include <assert.h>
+#include "EndianUtilities.h"
+#include "Logging.h"
+
+using namespace elftosb;
+
+//! \post Stream head points to just after the image header.
+//! \exception read_error Thrown if the image header is invalid.
+void EncoreBootImageReader::readImageHeader()
+{
+       // seek to beginning of the stream/file and read the plaintext header
+       m_stream.seekg(0, std::ios_base::beg);
+       if (m_stream.read((char *)&m_header, sizeof(m_header)).bad())
+       {
+               throw read_error("failed to read image header");
+       }
+       
+       m_header.m_flags = ENDIAN_LITTLE_TO_HOST_U16(m_header.m_flags);
+       m_header.m_imageBlocks = ENDIAN_LITTLE_TO_HOST_U32(m_header.m_imageBlocks);
+       m_header.m_firstBootTagBlock = ENDIAN_LITTLE_TO_HOST_U32(m_header.m_firstBootTagBlock);
+       m_header.m_firstBootableSectionID = ENDIAN_LITTLE_TO_HOST_U32(m_header.m_firstBootableSectionID);
+       m_header.m_keyCount = ENDIAN_LITTLE_TO_HOST_U16(m_header.m_keyCount);
+       m_header.m_keyDictionaryBlock = ENDIAN_LITTLE_TO_HOST_U16(m_header.m_keyDictionaryBlock);
+       m_header.m_headerBlocks = ENDIAN_LITTLE_TO_HOST_U16(m_header.m_headerBlocks);
+       m_header.m_sectionCount = ENDIAN_LITTLE_TO_HOST_U16(m_header.m_sectionCount);
+       m_header.m_sectionHeaderSize = ENDIAN_LITTLE_TO_HOST_U16(m_header.m_sectionHeaderSize);
+       m_header.m_timestamp = ENDIAN_LITTLE_TO_HOST_U64(m_header.m_timestamp);
+
+//     m_header.m_componentVersion.m_major = ENDIAN_BIG_TO_HOST_U16(m_header.m_componentVersion.m_major);
+//     m_header.m_componentVersion.m_minor = ENDIAN_BIG_TO_HOST_U16(m_header.m_componentVersion.m_minor);
+//     m_header.m_componentVersion.m_revision = ENDIAN_BIG_TO_HOST_U16(m_header.m_componentVersion.m_revision);
+
+//     m_header.m_productVersion.m_major = ENDIAN_BIG_TO_HOST_U16(m_header.m_productVersion.m_major);
+//     m_header.m_productVersion.m_minor = ENDIAN_BIG_TO_HOST_U16(m_header.m_productVersion.m_minor);
+//     m_header.m_productVersion.m_revision = ENDIAN_BIG_TO_HOST_U16(m_header.m_productVersion.m_revision);
+       
+       // check header signature 1
+       if (m_header.m_signature[0] != 'S' || m_header.m_signature[1] != 'T' || m_header.m_signature[2] != 'M' || m_header.m_signature[3] != 'P')
+       {
+               throw read_error("invalid signature 1");
+       }
+
+       // check header signature 2 for version 1.1 and greater
+       if ((m_header.m_majorVersion > 1 || (m_header.m_majorVersion == 1 && m_header.m_minorVersion >= 1)) && (m_header.m_signature2[0] != 's' || m_header.m_signature2[1] != 'g' || m_header.m_signature2[2] != 't' || m_header.m_signature2[3] != 'l'))
+       {
+//             throw read_error("invalid signature 2");
+               Log::log(Logger::WARNING, "warning: invalid signature 2\n");
+       }
+}
+
+//! \pre The image header must have already been read with a call to readImageHeader().
+//!
+void EncoreBootImageReader::computeHeaderDigest(sha1_digest_t & digest)
+{
+       CSHA1 hash;
+       hash.Reset();
+       hash.Update((uint8_t *)&m_header.m_signature, sizeof(m_header) - sizeof(sha1_digest_t));
+       hash.Final();
+       hash.GetHash(digest);
+}
+
+//! \pre The image header must have already been read.
+//! \pre The DEK must have been found already.
+//! \post The stream head is at the end of the digest.
+void EncoreBootImageReader::readImageDigest()
+{
+       unsigned digestPosition = sizeOfCipherBlocks(m_header.m_imageBlocks - 2);
+       m_stream.seekg(digestPosition, std::ios_base::beg);
+       
+       // read the two cipher blocks containing the digest, including padding
+       cipher_block_t digestBlocks[2];
+       if (m_stream.read((char *)&digestBlocks, sizeof(digestBlocks)).bad())
+       {
+               throw read_error("failed to read image digest");
+       }
+       
+       // decrypt the digest
+       if (isEncrypted())
+       {
+               Rijndael cipher;
+               cipher.init(Rijndael::CBC, Rijndael::Decrypt, m_dek, Rijndael::Key16Bytes, m_header.m_iv);
+               cipher.blockDecrypt((uint8_t *)&digestBlocks, sizeof(digestBlocks) * 8, (uint8_t *)&digestBlocks);
+       }
+       
+       // copy the digest out of the padded blocks
+       memcpy(m_digest, &digestBlocks, sizeof(m_digest));
+}
+
+//! \pre The image header must have already been read with a call to readImageHeader().
+//! \post The stream head is at the end of the image minus the last two cipher blocks.
+//! \param digest Where to store the resulting digest.
+//! \exception read_error Thrown if the image header is invalid.
+void EncoreBootImageReader::computeImageDigest(sha1_digest_t & digest)
+{
+       m_stream.seekg(0, std::ios_base::beg);
+       
+       CSHA1 hash;
+       hash.Reset();
+       
+       unsigned blockCount = m_header.m_imageBlocks - 2; // exclude digest at end of image
+       while (blockCount--)
+       {
+               cipher_block_t block;
+               if (m_stream.read((char *)&block, sizeof(block)).bad())
+               {
+                       throw read_error("failed to read block while computing image digest");
+               }
+               hash.Update(block, sizeof(block));
+       }
+       
+       hash.Final();
+       hash.GetHash(digest);
+}
+
+//! \pre Image header must have been read before this method is called.
+//!
+void EncoreBootImageReader::readSectionTable()
+{
+       // seek to the table
+       m_stream.seekg(sizeOfCipherBlocks(m_header.m_headerBlocks), std::ios_base::beg);
+       
+       unsigned sectionCount = m_header.m_sectionCount;
+       while (sectionCount--)
+       {
+               EncoreBootImage::section_header_t header;
+               if (m_stream.read((char *)&header, sizeof(header)).bad())
+               {
+                       throw read_error("failed to read section header");
+               }
+               
+               // swizzle section header
+               header.m_tag = ENDIAN_LITTLE_TO_HOST_U32(header.m_tag);
+               header.m_offset = ENDIAN_LITTLE_TO_HOST_U32(header.m_offset);
+               header.m_length = ENDIAN_LITTLE_TO_HOST_U32(header.m_length);
+               header.m_flags = ENDIAN_LITTLE_TO_HOST_U32(header.m_flags);
+               
+               m_sections.push_back(header);
+       }
+}
+
+//! Requires that an OTP key has been provided as the sole argument. Passing the
+//! key into this method lets the caller search the key dictionary for any number
+//! of keys and determine which are valid. If \a kek is found in the dictionary,
+//! the decrypted DEK is saved and true is returned. A result of false means
+//! that \a kek was not found.
+//!
+//! \pre The image header and section table must have been read already.
+//! \post The stream head points somewhere inside the key dictionary, or just after it.
+//! \post If the search was successful, the #m_dek member will contain the decrypted
+//!            session key. Otherwise #m_dek is not modified.
+//! \param kek Search for this KEK in the dictionary.
+//! \retval true The DEK was found and decrypted. True is also returned when the
+//!            image is not encrypted at all.
+//! \retval false No matching key entry was found. The image cannot be decrypted.
+bool EncoreBootImageReader::readKeyDictionary(const AESKey<128> & kek)
+{
+       // do nothing if the image is not encrypted
+       if (!isEncrypted())
+       {
+               return true;
+       }
+       
+       // first compute a CBC-MAC over the image header with our KEK
+       RijndaelCBCMAC mac(kek);
+       mac.update((const uint8_t *)&m_header, sizeof(m_header));
+       
+       // run the CBC-MAC over each entry in the section table too
+       section_array_t::iterator it = m_sections.begin();
+       for (; it != m_sections.end(); ++it)
+       {
+               mac.update((const uint8_t *)&(*it), sizeof(EncoreBootImage::section_header_t));
+       }
+       
+       // get the CBC-MAC result
+       mac.finalize();
+       const RijndaelCBCMAC::block_t & macResult = mac.getMAC();
+       
+       // seek to the key dictionary
+       m_stream.seekg(sizeOfCipherBlocks(m_header.m_keyDictionaryBlock), std::ios_base::beg);
+       
+       // decipher each key entry
+       unsigned entries = m_header.m_keyCount;
+       while (entries--)
+       {
+               // read the entry
+               EncoreBootImage::dek_dictionary_entry_t entry;
+               if (m_stream.read((char *)&entry, sizeof(entry)).bad())
+               {
+                       throw read_error("failed to read key dictionary entry");
+               }
+               
+               // compare the CBC-MAC we computed with the one in this entry
+               if (memcmp(macResult, entry.m_mac, sizeof(cipher_block_t)) == 0)
+               {
+                       // it's a match! now decrypt this entry's key in place
+                       Rijndael cipher;
+                       cipher.init(Rijndael::CBC, Rijndael::Decrypt, kek, Rijndael::Key16Bytes, m_header.m_iv);
+                       cipher.blockDecrypt(entry.m_dek, sizeof(entry.m_dek) * 8, entry.m_dek);
+                       
+                       m_dek = entry.m_dek;
+                       memset(entry.m_dek, 0, sizeof(entry.m_dek)); // wipe the key value from memory
+                       return true;
+               }
+       }
+       
+       // if we exit the loop normally then no matching MAC was found
+       return false;
+}
+
+//! Before the boot tag is added to the #m_bootTags member, some basic checks are performed.
+//! The command tag field is checked to make sure it matches #ROM_TAG_CMD. And
+//! the checksum field is verified to be sure it's correct.
+//!
+//! After the call to this method returns, the array of boot tags is accessible
+//! with the getBootTags() method. The array is sorted in the order in which
+//! the boot tags appeared in the image.
+//!
+//! \pre Image header must have been read.
+//! \pre Key dictionary must have been read and a valid DEK found.
+//! \post The stream head is left pointing just after the last boot tag.
+//! \exception read_error A failure to read the boot tag, or a failure on one
+//!            of the consistency checks will cause this exception to be thrown.
+void EncoreBootImageReader::readBootTags()
+{
+       assert(m_header.m_firstBootTagBlock != 0);
+       
+       unsigned bootTagOffset = m_header.m_firstBootTagBlock;
+       
+       while (1)
+       {
+               // seek to this boot tag and read it into a temporary buffer
+               EncoreBootImage::boot_command_t header;
+               m_stream.seekg(sizeOfCipherBlocks(bootTagOffset), std::ios_base::beg);
+               if (m_stream.read((char *)&header, sizeof(header)).bad())
+               {
+                       throw read_error("failed to read boot tag");
+               }
+               
+               // swizzle to command header
+               header.m_flags = ENDIAN_LITTLE_TO_HOST_U16(header.m_flags);
+               header.m_address = ENDIAN_LITTLE_TO_HOST_U32(header.m_address);
+               header.m_count = ENDIAN_LITTLE_TO_HOST_U32(header.m_count);
+               header.m_data = ENDIAN_LITTLE_TO_HOST_U32(header.m_data);
+               
+               // decrypt in place
+               if (isEncrypted())
+               {
+                       Rijndael cipher;
+                       cipher.init(Rijndael::CBC, Rijndael::Decrypt, m_dek, Rijndael::Key16Bytes, m_header.m_iv);
+                       cipher.blockDecrypt((uint8_t *)&header, sizeof(header) * 8, (uint8_t *)&header);
+               }
+               
+               // perform some basic checks
+               if (header.m_tag != EncoreBootImage::ROM_TAG_CMD)
+               {
+                       throw read_error("boot tag is wrong command type");
+               }
+               
+               uint8_t checksum = calculateCommandChecksum(header);
+               if (checksum != header.m_checksum)
+               {
+                       throw read_error("boot tag checksum is invalid");
+               }
+               
+               // save this boot tag
+               m_bootTags.push_back(header);
+               
+               // and finally, update offset and break out of loop
+               bootTagOffset += header.m_count + 1; // include this boot tag in offset
+               if (header.m_flags & EncoreBootImage::ROM_LAST_TAG || bootTagOffset >= m_header.m_imageBlocks - 2)
+               {
+                       break;
+               }
+       }
+}
+
+uint8_t EncoreBootImageReader::calculateCommandChecksum(EncoreBootImage::boot_command_t & header)
+{
+       uint8_t * bytes = reinterpret_cast<uint8_t *>(&header);
+       uint8_t checksum = 0x5a;
+       int i;
+       
+       // start at one to skip checksum field
+       for (i = 1; i < sizeof(header); ++i)
+       {
+               checksum += bytes[i];
+       }
+       
+       return checksum;
+}
+
+//! \param index The index of the section to read.
+//!
+//! \pre Both the image header and section table must have been read already before
+//!            calling this method.
+//! \exception read_error This exception is raised if the stream reports an error while
+//!            trying to read from the section.
+EncoreBootImage::Section * EncoreBootImageReader::readSection(unsigned index)
+{
+       // look up section header
+       assert(index < m_sections.size());
+       EncoreBootImage::section_header_t & header = m_sections[index];
+       
+       // seek to the section
+       m_stream.seekg(sizeOfCipherBlocks(header.m_offset), std::ios_base::beg);
+       
+       uint8_t * contents = NULL;
+       try
+       {
+               // allocate memory for the section contents and read the whole thing
+               unsigned contentLength = sizeOfCipherBlocks(header.m_length);
+               contents = new uint8_t[contentLength];
+               if (m_stream.read((char *)contents, contentLength).bad())
+               {
+                       throw read_error("failed to read section");
+               }
+               
+               // decrypt the entire section at once, if the image is encrypted and
+               // the cleartext flag is not set
+               if (isEncrypted() && (header.m_flags & EncoreBootImage::ROM_SECTION_CLEARTEXT) == 0)
+               {
+                       Rijndael cipher;
+                       cipher.init(Rijndael::CBC, Rijndael::Decrypt, m_dek, Rijndael::Key16Bytes, m_header.m_iv);
+                       cipher.blockDecrypt(contents, contentLength * 8, contents);
+               }
+               
+               // create section object
+               EncoreBootImage::Section * resultSection = NULL;
+               if (header.m_flags & EncoreBootImage::ROM_SECTION_BOOTABLE)
+               {
+                       // a boot command section.
+                       EncoreBootImage::BootSection * bootSection = new EncoreBootImage::BootSection(header.m_tag);
+                       
+                       bootSection->fillFromData((cipher_block_t *)contents, header.m_length);
+                       
+                       resultSection = bootSection;
+               }
+               else
+               {
+                       // this is a raw data section
+                       EncoreBootImage::DataSection * dataSection = new EncoreBootImage::DataSection(header.m_tag);
+                       dataSection->setDataNoCopy(contents, contentLength);
+                       contents = NULL;
+                       resultSection = dataSection;
+               }
+               
+               return resultSection;
+       }
+       catch (...)
+       {
+               if (contents)
+               {
+                       delete [] contents;
+               }
+               throw;
+       }
+}
+
+
diff --git a/tools/elftosb/sbtool/EncoreBootImageReader.h b/tools/elftosb/sbtool/EncoreBootImageReader.h
new file mode 100644 (file)
index 0000000..6150a92
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * File:       EncoreBootImageReader.h
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+#if !defined(_EncoreBootImageReader_h_)
+#define _EncoreBootImageReader_h_
+
+#include "EncoreBootImage.h"
+
+namespace elftosb
+{
+
+/*!
+ * \brief Reads a Piano/Encore boot image from an input stream.
+ */
+class EncoreBootImageReader
+{
+public:
+       /*!
+        * \brief Exception class used for error found while reading a boot image.
+        */
+       class read_error : public std::runtime_error
+       {
+       public:
+               //! \brief Constructor.
+               read_error(const std::string & msg) : std::runtime_error(msg) {}
+       };
+       
+       //! \brief An array of section headers.
+       typedef std::vector<EncoreBootImage::section_header_t> section_array_t;
+       
+       //! \brief An array of boot tags.
+       typedef std::vector<EncoreBootImage::boot_command_t> boot_tag_array_t;
+       
+public:
+       //! \brief Default constructor.
+       EncoreBootImageReader(std::istream & stream) : m_stream(stream) {}
+       
+       //! \brief Destructor.
+       virtual ~EncoreBootImageReader() {}
+       
+       //! \name Decryption key
+       //! These methods provide access to the Data Encryption Key (DEK). Normally
+       //! the DEK is discovered using the readKeyDictionary() method.
+       //@{
+       inline void setKey(const AESKey<128> & key) { m_dek = key; }
+       inline const AESKey<128> & getKey() const { return m_dek; }
+       //@}
+       
+       //! \name Readers
+       //! This group of methods is responsible for reading and parsing different
+       //! pieces and parts of the boot image file.
+       //@{
+       //! \brief Reads the header from the image.
+       void readImageHeader();
+       
+       //! \brief Computes the actual SHA-1 digest of the image header.
+       void computeHeaderDigest(sha1_digest_t & digest);
+       
+       //! \brief Reads the digest at the end of the image.
+       void readImageDigest();
+       
+       //! \brief Run a SHA-1 digest over the entire image.
+       void computeImageDigest(sha1_digest_t & digest);
+       
+       //! \brief Read the plaintext section table entries.
+       void readSectionTable();
+       
+       //! \brief Reads the key dictionary, if the image is encrypted.
+       bool readKeyDictionary(const AESKey<128> & kek);
+       
+       //! \brief
+       void readBootTags();
+       
+       //! \brief
+       EncoreBootImage::Section * readSection(unsigned index);
+       //@}
+       
+       //! \name Accessors
+       //! Information retrieved with reader methods is accessible through
+       //! these methods.
+       //@{
+       //! \brief Returns whether the image is encrypted or not.
+       //! \pre The header must have been read already.
+       inline bool isEncrypted() const { return m_header.m_keyCount > 0; }
+       
+       //! \brief Returns a reference to the image's header.
+       const EncoreBootImage::boot_image_header_t & getHeader() const { return m_header; }
+       
+       //! \brief Returns a reference to the SHA-1 digest read from the image.
+       const sha1_digest_t & getDigest() const { return m_digest; }
+       
+       //! \brief Returns a reference to the STL container holding the section headers.
+       inline const section_array_t & getSections() const { return m_sections; }
+       
+       //! \brief Returns a reference to the STL container holding the boot tags.
+       inline const boot_tag_array_t & getBootTags() const { return m_bootTags; }
+       //@}
+       
+protected:
+       std::istream & m_stream;        //!< The input stream to read the image from.
+       AESKey<128> m_dek;      //!< DEK (data encryption key) read from the key dictionary.
+       EncoreBootImage::boot_image_header_t m_header;  //!< Header from the boot image.
+       sha1_digest_t m_digest; //!< SHA-1 digest as read from the image.
+       section_array_t m_sections;     //!< The section table.
+       boot_tag_array_t m_bootTags;    //!< The array of boot tags read from the image.
+       
+protected:
+       //! \brief Calculates the 8-bit checksum on a boot command header.
+       uint8_t calculateCommandChecksum(EncoreBootImage::boot_command_t & header);
+};
+
+}; // namespace elftosb
+
+#endif // _EncoreBootImageReader_h_
diff --git a/tools/elftosb/sbtool/sbtool.cpp b/tools/elftosb/sbtool/sbtool.cpp
new file mode 100644 (file)
index 0000000..c83cee2
--- /dev/null
@@ -0,0 +1,626 @@
+/*
+ * File:       sbtool.cpp
+ *
+ * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
+ * See included license file for license details.
+ */
+
+#include "stdafx.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <stdlib.h>
+#include <stdexcept>
+#include <stdio.h>
+#include "options.h"
+#include "EncoreBootImage.h"
+#include "smart_ptr.h"
+#include "Logging.h"
+#include "EncoreBootImageReader.h"
+#include "format_string.h"
+
+using namespace elftosb;
+
+//! The tool's name.
+const char k_toolName[] = "sbtool";
+
+//! Current version number for the tool.
+const char k_version[] = "1.1.4";
+
+//! Copyright string.
+const char k_copyright[] = "Copyright (c) 2006-2010 Freescale Semiconductor, Inc.\nAll rights reserved.";
+
+//! Definition of command line options.
+static const char * k_optionsDefinition[] = {
+       "?|help",
+       "v|version",
+       "k:key <file>",
+       "z|zero-key",
+       "x:extract",
+       "b|binary",
+       "d|debug",
+       "q|quiet",
+       "V|verbose",
+       NULL
+};
+
+//! Help string.
+const char k_usageText[] = "\nOptions:\n\
+  -?/--help                    Show this help\n\
+  -v/--version                 Display tool version\n\
+  -k/--key <file>              Add OTP key used for decryption\n\
+  -z/--zero-key                Add default key of all zeroes\n\
+  -x/--extract <index>         Extract section number <index>\n\
+  -b/--binary                  Extract section data as binary\n\
+  -d/--debug                   Enable debug output\n\
+  -q/--quiet                   Output only warnings and errors\n\
+  -V/--verbose                 Print extra detailed log information\n\n";
+
+//! An array of strings.
+typedef std::vector<std::string> string_vector_t;
+
+// prototypes
+int main(int argc, char* argv[], char* envp[]);
+
+/*!
+ * \brief Class that encapsulates the sbtool interface.
+ *
+ * A single global logger instance is created during object construction. It is
+ * never freed because we need it up to the last possible minute, when an
+ * exception could be thrown.
+ */
+class sbtool
+{
+protected:
+       int m_argc;                                                     //!< Number of command line arguments.
+       char ** m_argv;                                         //!< String value for each command line argument.
+       StdoutLogger * m_logger;                        //!< Singleton logger instance.
+       string_vector_t m_keyFilePaths;         //!< Paths to OTP key files.
+       string_vector_t m_positionalArgs;       //!< Arguments coming after explicit options.
+       bool m_isVerbose;                                       //!< Whether the verbose flag was turned on.
+       bool m_useDefaultKey;                                   //!< Include a default (zero) crypto key.
+       bool m_doExtract;                                       //!< True if extract mode is on.
+       unsigned m_sectionIndex;                                //!< Index of section to extract.
+       bool m_extractBinary;                           //!< True if extraction output is binary, false for hex.
+       smart_ptr<EncoreBootImageReader> m_reader;      //!< Boot image reader object.
+       
+public:
+       /*!
+        * Constructor.
+        *
+        * Creates the singleton logger instance.
+        */
+       sbtool(int argc, char * argv[])
+       :       m_argc(argc),
+               m_argv(argv),
+               m_logger(0),
+               m_keyFilePaths(),
+               m_positionalArgs(),
+               m_isVerbose(false),
+               m_useDefaultKey(false),
+               m_doExtract(false),
+               m_sectionIndex(0),
+               m_extractBinary(false),
+               m_reader()
+       {
+               // create logger instance
+               m_logger = new StdoutLogger();
+               m_logger->setFilterLevel(Logger::INFO);
+               Log::setLogger(m_logger);
+       }
+       
+       /*!
+        * Destructor.
+        */
+       ~sbtool()
+       {
+       }
+       
+       /*!
+        * Reads the command line options passed into the constructor.
+        *
+        * This method can return a return code to its caller, which will cause the
+        * tool to exit immediately with that return code value. Normally, though, it
+        * will return -1 to signal that the tool should continue to execute and
+        * all options were processed successfully.
+        *
+        * The Options class is used to parse command line options. See
+        * #k_optionsDefinition for the list of options and #k_usageText for the
+        * descriptive help for each option.
+        *
+        * \retval -1 The options were processed successfully. Let the tool run normally.
+        * \return A zero or positive result is a return code value that should be
+        *              returned from the tool as it exits immediately.
+        */
+       int processOptions()
+       {
+               Options options(*m_argv, k_optionsDefinition);
+               OptArgvIter iter(--m_argc, ++m_argv);
+               
+               // process command line options
+               int optchar;
+               const char * optarg;
+               while (optchar = options(iter, optarg))
+               {
+                       switch (optchar)
+                       {
+                               case '?':
+                                       printUsage(options);
+                                       return 0;
+                               
+                               case 'v':
+                                       printf("%s %s\n%s\n", k_toolName, k_version, k_copyright);
+                                       return 0;
+                                       
+                               case 'k':
+                                       m_keyFilePaths.push_back(optarg);
+                                       break;
+                               
+                               case 'z':
+                                       m_useDefaultKey = true;
+                                       break;
+                               
+                               case 'x':
+                                       m_doExtract = true;
+                                       m_sectionIndex = strtoul(optarg, NULL, 0);
+                                       break;
+                               
+                               case 'b':
+                                       m_extractBinary = true;
+                                       Log::getLogger()->setFilterLevel(Logger::WARNING);
+                                       break;
+                                       
+                               case 'd':
+                                       Log::getLogger()->setFilterLevel(Logger::DEBUG);
+                                       break;
+                                       
+                               case 'q':
+                                       Log::getLogger()->setFilterLevel(Logger::WARNING);
+                                       break;
+                                       
+                               case 'V':
+                                       m_isVerbose = true;
+                                       break;
+                               
+                               default:
+                                       Log::log(Logger::ERROR, "error: unrecognized option\n\n");
+                                       printUsage(options);
+                                       return 1;
+                       }
+               }
+               
+               // handle positional args
+               if (iter.index() < m_argc)
+               {
+//                     Log::SetOutputLevel leveler(Logger::DEBUG);
+//                     Log::log("positional args:\n");
+                       int i;
+                       for (i = iter.index(); i < m_argc; ++i)
+                       {
+//                             Log::log("%d: %s\n", i - iter.index(), m_argv[i]);
+                               m_positionalArgs.push_back(m_argv[i]);
+                       }
+               }
+               
+               // all is well
+               return -1;
+       }
+
+       /*!
+        * Prints help for the tool.
+        */
+       void printUsage(Options & options)
+       {
+               options.usage(std::cout, "sb-file");
+               printf(k_usageText, k_toolName);
+       }
+       
+       /*!
+        * Core of the tool. Calls processOptions() to handle command line options
+        * before performing the real work the tool does.
+        */
+       int run()
+       {
+               try
+               {
+                       // read command line options
+                       int result;
+                       if ((result = processOptions()) != -1)
+                       {
+                               return result;
+                       }
+                       
+                       // set verbose logging
+                       setVerboseLogging();
+                       
+                       // make sure a file was provided
+                       if (m_positionalArgs.size() < 1)
+                       {
+                               throw std::runtime_error("no sb file path was provided");
+                       }
+                       
+                       // read the boot image
+                       readBootImage();
+               }
+               catch (std::exception & e)
+               {
+                       Log::log(Logger::ERROR, "error: %s\n", e.what());
+                       return 1;
+               }
+               catch (...)
+               {
+                       Log::log(Logger::ERROR, "error: unexpected exception\n");
+                       return 1;
+               }
+               
+               return 0;
+       }
+       
+       /*!
+        * \brief Turns on verbose logging.
+        */
+       void setVerboseLogging()
+       {
+               if (m_isVerbose)
+               {
+                       // verbose only affects the INFO and DEBUG filter levels
+                       // if the user has selected quiet mode, it overrides verbose
+                       switch (Log::getLogger()->getFilterLevel())
+                       {
+                               case Logger::INFO:
+                                       Log::getLogger()->setFilterLevel(Logger::INFO2);
+                                       break;
+                               case Logger::DEBUG:
+                                       Log::getLogger()->setFilterLevel(Logger::DEBUG2);
+                                       break;
+                       }
+               }
+       }
+       
+       /*!
+        * \brief Opens and reads the boot image identified on the command line.
+        * \pre At least one position argument must be present.
+        */
+       void readBootImage()
+       {
+               Log::SetOutputLevel infoLevel(Logger::INFO);
+               
+               // open the sb file stream
+               std::ifstream sbStream(m_positionalArgs[0].c_str(), std::ios_base::binary | std::ios_base::in);
+               if (!sbStream.is_open())
+               {
+                       throw std::runtime_error("failed to open input file");
+               }
+               
+               // create the boot image reader
+               m_reader = new EncoreBootImageReader(sbStream);
+               
+               // read image header
+               m_reader->readImageHeader();
+               const EncoreBootImage::boot_image_header_t & header = m_reader->getHeader();
+               if (header.m_majorVersion > 1)
+               {
+                       throw std::runtime_error(format_string("boot image format version is too new (format version %d.%d)\n", header.m_majorVersion, header.m_minorVersion));
+               }
+               Log::log("---- Boot image header ----\n");
+               dumpImageHeader(header);
+               
+               // compute SHA-1 over image header and test against the digest stored in the header
+               sha1_digest_t computedDigest;
+               m_reader->computeHeaderDigest(computedDigest);
+               if (compareDigests(computedDigest, m_reader->getHeader().m_digest))
+               {
+                       Log::log("Header digest is correct.\n");
+               }
+               else
+               {
+                       Log::log(Logger::WARNING, "warning: stored SHA-1 header digest does not match the actual header digest\n");
+                       Log::log(Logger::WARNING, "\n---- Actual SHA-1 digest of image header ----\n");
+                       logHexArray(Logger::WARNING, (uint8_t *)&computedDigest, sizeof(computedDigest));
+               }
+               
+               // read the section table
+               m_reader->readSectionTable();
+               const EncoreBootImageReader::section_array_t & sectionTable = m_reader->getSections();
+               EncoreBootImageReader::section_array_t::const_iterator it = sectionTable.begin();
+               Log::log("\n---- Section table ----\n");
+               unsigned n = 0;
+               for (; it != sectionTable.end(); ++it, ++n)
+               {
+                       const EncoreBootImage::section_header_t & sectionHeader = *it;
+                       Log::log("Section %d:\n", n);
+                       dumpSectionHeader(sectionHeader);
+               }
+               
+               // read the key dictionary
+               // XXX need to support multiple keys, not just the first!
+               if (m_reader->isEncrypted())
+               {
+                       Log::log("\n---- Key dictionary ----\n");
+                       if (m_keyFilePaths.size() > 0 || m_useDefaultKey)
+                       {
+                               if (m_keyFilePaths.size() > 0)
+                               {
+                                       std::string & keyPath = m_keyFilePaths[0];
+                                       std::ifstream keyStream(keyPath.c_str(), std::ios_base::binary | std::ios_base::in);
+                                       if (!keyStream.is_open())
+                                       {
+                                               Log::log(Logger::WARNING, "warning: unable to read key %s\n", keyPath.c_str());
+                                       }
+                                       AESKey<128> kek(keyStream);
+                               
+                                       // search for this key in the key dictionary
+                                       if (!m_reader->readKeyDictionary(kek))
+                                       {
+                                               throw std::runtime_error("the provided key is not valid for this encrypted boot image");
+                                       }
+                                       
+                                       Log::log("\nKey %s was found in key dictionary.\n", keyPath.c_str());
+                               }
+                               else
+                               {
+                                       // default key of zero, overriden if -k was used
+                                       AESKey<128> defaultKek;
+                               
+                                       // search for this key in the key dictionary
+                                       if (!m_reader->readKeyDictionary(defaultKek))
+                                       {
+                                               throw std::runtime_error("the default key is not valid for this encrypted boot image");
+                                       }
+                                       
+                                       Log::log("\nDefault key was found in key dictionary.\n");
+                               }
+                               
+                               // print out the DEK
+                               AESKey<128> dek = m_reader->getKey();
+                               std::stringstream dekStringStream(std::ios_base::in | std::ios_base::out);
+                               dek.writeToStream(dekStringStream);
+                               std::string dekString = dekStringStream.str();
+//                             Log::log("\nData encryption key: %s\n", dekString.c_str());
+                               Log::log("\nData encryption key:\n");
+                               logHexArray(Logger::INFO, (const uint8_t *)&dek.getKey(), sizeof(AESKey<128>::key_t));
+                       }
+                       else
+                       {
+                               throw std::runtime_error("the image is encrypted but no key was provided");
+                       }
+               }
+               
+               // read the SHA-1 digest over the entire image. this is done after
+               // reading the key dictionary because the digest is encrypted in
+               // encrypted boot images.
+               m_reader->readImageDigest();
+               const sha1_digest_t & embeddedDigest = m_reader->getDigest();
+               Log::log("\n---- SHA-1 digest of entire image ----\n");
+               logHexArray(Logger::INFO, (const uint8_t *)&embeddedDigest, sizeof(embeddedDigest));
+               
+               // compute the digest over the entire image and compare
+               m_reader->computeImageDigest(computedDigest);
+               if (compareDigests(computedDigest, embeddedDigest))
+               {
+                       Log::log("Image digest is correct.\n");
+               }
+               else
+               {
+                       Log::log(Logger::WARNING, "warning: stored SHA-1 digest does not match the actual digest\n");
+                       Log::log(Logger::WARNING, "\n---- Actual SHA-1 digest of entire image ----\n");
+                       logHexArray(Logger::WARNING, (uint8_t *)&computedDigest, sizeof(computedDigest));
+               }
+               
+               // read the boot tags
+               m_reader->readBootTags();
+               Log::log("\n---- Boot tags ----\n");
+               unsigned block = header.m_firstBootTagBlock;
+               const EncoreBootImageReader::boot_tag_array_t & tags = m_reader->getBootTags();
+               EncoreBootImageReader::boot_tag_array_t::const_iterator tagIt = tags.begin();
+               for (n = 0; tagIt != tags.end(); ++tagIt, ++n)
+               {
+                       const EncoreBootImage::boot_command_t & command = *tagIt;
+                       Log::log("%04u: @ block %06u | id=0x%08x | length=%06u | flags=0x%08x\n", n, block, command.m_address, command.m_count, command.m_data);
+                                       
+                       if (command.m_data & EncoreBootImage::ROM_SECTION_BOOTABLE)
+                       {
+                               Log::log("        0x1 = ROM_SECTION_BOOTABLE\n");
+                       }
+                       
+                       if (command.m_data & EncoreBootImage::ROM_SECTION_CLEARTEXT)
+                       {
+                               Log::log("        0x2 = ROM_SECTION_CLEARTEXT\n");
+                       }
+                       
+                       block += command.m_count + 1;
+               }
+        
+        // now read all of the sections
+               Log::log(Logger::INFO2, "\n---- Sections ----\n");
+        for (n = 0; n < header.m_sectionCount; ++n)
+        {
+            EncoreBootImage::Section * section = m_reader->readSection(n);
+            section->debugPrint();
+                       
+                       // Check if this is the section the user wants to extract.
+                       if (m_doExtract && n == m_sectionIndex)
+                       {
+                               extractSection(section);
+                       }
+        }
+       }
+       
+       //! \brief Dumps the contents of a section to stdout.
+       //!
+       //! If #m_extractBinary is true then the contents are written as
+       //! raw binary to stdout. Otherwise the data is formatted using
+       //! logHexArray().
+       void extractSection(EncoreBootImage::Section * section)
+       {
+               // Allocate buffer to hold section data.
+               unsigned blockCount = section->getBlockCount();
+               unsigned dataLength = sizeOfCipherBlocks(blockCount);
+               smart_array_ptr<uint8_t> buffer = new uint8_t[dataLength];
+               cipher_block_t * data = reinterpret_cast<cipher_block_t *>(buffer.get());
+               
+               // Read section data into the buffer one block at a time.
+               unsigned offset;
+               for (offset = 0; offset < blockCount;)
+               {
+                       unsigned blocksRead = section->getBlocks(offset, 1, data);
+                       offset += blocksRead;
+                       data += blocksRead;
+               }
+               
+               // Print header.
+               Log::log(Logger::INFO, "\nSection %d contents:\n", m_sectionIndex);
+               
+               // Now dump the extracted data to stdout.
+               if (m_extractBinary)
+               {
+                       if (fwrite(buffer.get(), 1, dataLength, stdout) != dataLength)
+                       {
+                               throw std::runtime_error(format_string("failed to write data to stdout (%d)", ferror(stdout)));
+                       }
+               }
+               else
+               {
+                       // Use the warning log level so the data will be visible even in quiet mode.
+                       logHexArray(Logger::WARNING, buffer, dataLength);
+               }
+       }
+       
+       //! \brief Compares two SHA-1 digests and returns whether they are equal.
+       //! \retval true The two digests are equal.
+       //! \retval false The \a a and \a b digests are different from each other.
+       bool compareDigests(const sha1_digest_t & a, const sha1_digest_t & b)
+       {
+               return memcmp(a, b, sizeof(sha1_digest_t)) == 0;
+       }
+       
+       /*
+       struct boot_image_header_t
+       {
+               union
+               {
+                       sha1_digest_t m_digest;         //!< SHA-1 digest of image header. Also used as the crypto IV.
+                       struct
+                       {
+                               cipher_block_t m_iv;    //!< The first four bytes of the digest form the initialization vector.
+                               uint8_t m_extra[4];             //!< The leftover top four bytes of the SHA-1 digest.
+                       };
+               };
+               uint8_t m_signature[4];                 //!< 'STMP', see #ROM_IMAGE_HEADER_SIGNATURE.
+               uint16_t m_version;                             //!< Version of the boot image format, see #ROM_BOOT_IMAGE_VERSION.
+               uint16_t m_flags;                               //!< Flags or options associated with the entire image.
+               uint32_t m_imageBlocks;                 //!< Size of entire image in blocks.
+               uint32_t m_firstBootTagBlock;   //!< Offset from start of file to the first boot tag, in blocks.
+               section_id_t m_firstBootableSectionID;  //!< ID of section to start booting from.
+               uint16_t m_keyCount;                    //!< Number of entries in DEK dictionary.
+               uint16_t m_keyDictionaryBlock;  //!< Starting block number for the key dictionary.
+               uint16_t m_headerBlocks;                //!< Size of this header, including this size word, in blocks.
+               uint16_t m_sectionCount;                //!< Number of section headers in this table.
+               uint16_t m_sectionHeaderSize;   //!< Size in blocks of a section header.
+               uint8_t m_padding0[6];                  //!< Padding to align #m_timestamp to long word.
+               uint64_t m_timestamp;                   //!< Timestamp when image was generated in microseconds since 1-1-2000.
+               version_t m_productVersion;             //!< Product version.
+               version_t m_componentVersion;   //!< Component version.
+               uint16_t m_driveTag;
+               uint8_t m_padding1[6];          //!< Padding to round up to next cipher block.
+       };
+       */
+       void dumpImageHeader(const EncoreBootImage::boot_image_header_t & header)
+       {
+               version_t vers;
+
+               Log::SetOutputLevel infoLevel(Logger::INFO);
+               Log::log("Signature 1:           %c%c%c%c\n", header.m_signature[0], header.m_signature[1], header.m_signature[2], header.m_signature[3]);
+               Log::log("Signature 2:           %c%c%c%c\n", header.m_signature2[0], header.m_signature2[1], header.m_signature2[2], header.m_signature2[3]);
+               Log::log("Format version:        %d.%d\n", header.m_majorVersion, header.m_minorVersion);
+               Log::log("Flags:                 0x%04x\n", header.m_flags);
+               Log::log("Image blocks:          %u\n", header.m_imageBlocks);
+               Log::log("First boot tag block:  %u\n", header.m_firstBootTagBlock);
+               Log::log("First boot section ID: 0x%08x\n", header.m_firstBootableSectionID);
+               Log::log("Key count:             %u\n", header.m_keyCount);
+               Log::log("Key dictionary block:  %u\n", header.m_keyDictionaryBlock);
+               Log::log("Header blocks:         %u\n", header.m_headerBlocks);
+               Log::log("Section count:         %u\n", header.m_sectionCount);
+               Log::log("Section header size:   %u\n", header.m_sectionHeaderSize);
+               Log::log("Timestamp:             %llu\n", header.m_timestamp);
+               vers = header.m_productVersion;
+               vers.fixByteOrder();
+               Log::log("Product version:       %x.%x.%x\n", vers.m_major, vers.m_minor, vers.m_revision);
+               vers = header.m_componentVersion;
+               vers.fixByteOrder();
+               Log::log("Component version:     %x.%x.%x\n", vers.m_major, vers.m_minor, vers.m_revision);
+               if (header.m_majorVersion == 1 && header.m_minorVersion >= 1)
+               {
+                       Log::log("Drive tag:             0x%04x\n", header.m_driveTag);
+               }
+               Log::log("SHA-1 digest of header:\n");
+               logHexArray(Logger::INFO, (uint8_t *)&header.m_digest, sizeof(header.m_digest));
+       }
+       
+       void dumpSectionHeader(const EncoreBootImage::section_header_t & header)
+       {
+               Log::SetOutputLevel infoLevel(Logger::INFO);
+               Log::log("    Identifier: 0x%x\n", header.m_tag);
+               Log::log("    Offset:     %d block%s (%d bytes)\n", header.m_offset, header.m_offset!=1?"s":"", sizeOfCipherBlocks(header.m_offset));
+               Log::log("    Length:     %d block%s (%d bytes)\n", header.m_length, header.m_length!=1?"s":"", sizeOfCipherBlocks(header.m_length));
+               Log::log("    Flags:      0x%08x\n", header.m_flags);
+               
+               if (header.m_flags & EncoreBootImage::ROM_SECTION_BOOTABLE)
+               {
+                       Log::log("                0x1 = ROM_SECTION_BOOTABLE\n");
+               }
+               
+               if (header.m_flags & EncoreBootImage::ROM_SECTION_CLEARTEXT)
+               {
+                       Log::log("                0x2 = ROM_SECTION_CLEARTEXT\n");
+               }
+       }
+       
+       /*!
+        * \brief Log an array of bytes as hex.
+        */
+       void logHexArray(Logger::log_level_t level, const uint8_t * bytes, unsigned count)
+       {
+               Log::SetOutputLevel leveler(level);
+
+               unsigned i;
+               for (i = 0; i < count; ++i, ++bytes)
+               {
+                       if ((i % 16 == 0) && (i < count - 1))
+                       {
+                               if (i != 0)
+                               {
+                                       Log::log("\n");
+                               }
+                               Log::log("    0x%08x: ", i);
+                       }
+                       Log::log("%02x ", *bytes & 0xff);
+               }
+               
+               Log::log("\n");
+       }
+
+};
+
+/*!
+ * Main application entry point. Creates an sbtool instance and lets it take over.
+ */
+int main(int argc, char* argv[], char* envp[])
+{
+       try
+       {
+               return sbtool(argc, argv).run();
+       }
+       catch (...)
+       {
+               Log::log(Logger::ERROR, "error: unexpected exception\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+
+
+
+
diff --git a/tools/elftosb/sbtool/sbtool.vcproj b/tools/elftosb/sbtool/sbtool.vcproj
new file mode 100644 (file)
index 0000000..f2b24d8
--- /dev/null
@@ -0,0 +1,495 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9.00"\r
+       Name="sbtool"\r
+       ProjectGUID="{5C9AC9F0-C755-4BBB-B65B-78C5262A87D2}"\r
+       Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\elftosb2;..\winsupport;..\common"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="1"\r
+                               RuntimeTypeInfo="true"\r
+                               UsePrecompiledHeader="0"\r
+                               BrowseInformation="1"\r
+                               WarningLevel="2"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="4"\r
+                               DisableSpecificWarnings="4355"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/sbtool.exe"\r
+                               LinkIncremental="2"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(OutDir)/sbtool.pdb"\r
+                               SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="1"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"\r
+                               RuntimeLibrary="0"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               OutputFile="$(OutDir)/sbtool.exe"\r
+                               LinkIncremental="1"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <Filter\r
+                               Name="sbtool"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\EncoreBootImageReader.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath=".\sbtool.cpp"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="common"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\common\AESKey.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\AESKey.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Blob.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Blob.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\BootImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\crc.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\crc.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataSource.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataSource.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataTarget.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\DataTarget.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELF.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELFSourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\ELFSourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EncoreBootImage.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EncoreBootImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EndianUtilities.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EvalContext.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\EvalContext.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\format_string.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\format_string.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GHSSecInfo.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GHSSecInfo.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GlobMatcher.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\GlobMatcher.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\HexValues.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\HexValues.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\int_size.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Logging.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Logging.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Operation.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Operation.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionContext.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionDictionary.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OptionDictionary.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\options.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\options.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OutputSection.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\OutputSection.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Random.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Random.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\rijndael.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\rijndael.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\RijndaelCBCMAC.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\RijndaelCBCMAC.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SearchPath.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SHA1.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SHA1.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\smart_ptr.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SRecordSourceFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\SRecordSourceFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\stdafx.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\stdafx.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StELFFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StELFFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StExecutableImage.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StExecutableImage.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StringMatcher.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StSRecordFile.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\StSRecordFile.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Value.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Value.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Version.cpp"\r
+                                       >\r
+                               </File>\r
+                               <File\r
+                                       RelativePath="..\common\Version.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+                       <Filter\r
+                               Name="sbtol"\r
+                               >\r
+                               <File\r
+                                       RelativePath=".\EncoreBootImageReader.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+                       <Filter\r
+                               Name="common"\r
+                               >\r
+                               <File\r
+                                       RelativePath="..\common\SearchPath.h"\r
+                                       >\r
+                               </File>\r
+                       </Filter>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/tools/elftosb/stdafx.h b/tools/elftosb/stdafx.h
new file mode 100644 (file)
index 0000000..ce80458
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef stdafx_h_
+#define stdafx_h_
+
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+// Default to external release.
+#ifndef SGTL_INTERNAL
+    #define SGTL_INTERNAL 0
+#endif
+
+#include <iostream>
+#include <stdexcept>
+
+#if defined(WIN32)
+//#include <tchar.h>
+    
+    // define this macro for use in VC++
+    #if !defined(__LITTLE_ENDIAN__)
+        #define __LITTLE_ENDIAN__ 1
+    #endif // !defined(__LITTLE_ENDIAN__)
+#endif // defined(WIN32)
+
+#if defined(Linux)
+// For Linux systems only, types.h only defines the signed
+// integer types.  This is not professional code.
+// Update: They are defined in the header files in the more recent version of redhat enterprise gcc.
+#include "/usr/include/sys/types.h"
+//typedef unsigned long uint32_t;
+//typedef unsigned short uint16_t;
+//typedef unsigned char uint8_t;
+
+//#define TCHAR char
+//#define _tmain main
+
+    // give a default endian in case one is not defined on Linux (it should be, though)
+    #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+        #define __LITTLE_ENDIAN__ 1
+    #endif // !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
+
+#endif // defined(Linux)
+
+
+#if !defined(Linux)
+// redefine missing typedefs from stdint.h or syst/types.h
+
+typedef unsigned long uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+
+typedef long int32_t;
+typedef short int16_t;
+typedef char int8_t;
+#endif // !defined(Linux)
+
+#if !defined(TRUE)
+    #define TRUE 1
+#endif // !defined(TRUE)
+
+#if !defined(FALSE)
+    #define FALSE 0
+#endif // !defined(FALSE)
+
+#endif // stdafx_h_
diff --git a/tools/elftosb/test_elftosb.bat b/tools/elftosb/test_elftosb.bat
new file mode 100644 (file)
index 0000000..4f512be
--- /dev/null
@@ -0,0 +1,12 @@
+
+mkdir test_output
+
+.\elftosb2\Debug\elftosb -Vdz -p bdfiles -p test_files -fmx28 -c simple.e -o test_output\output1.sb plugin_hello redboot_gcc.srec hostlink
+.\sbtool\Debug\sbtool -Vdz test_output\output1.sb > test_output\output1.txt
+
+.\elftosb2\Debug\elftosb -Vdz -p bdfiles -p test_files -fmx28 -c habtest.bd -o test_output\output2.sb plugin_hello redboot_gcc.srec hostlink
+.\sbtool\Debug\sbtool -Vdz test_output\output2.sb > test_output\output2.txt
+
+.\elftosb2\Debug\elftosb -Vdz -p bdfiles -p test_files -fmx28 -c basic_test_cmd.e -o test_output\output3.sb plugin_hello redboot_gcc.srec hostlink sd_player_gcc
+.\sbtool\Debug\sbtool -Vdz test_output\output2.sb > test_output\output3.txt
+
diff --git a/tools/elftosb/test_elftosb.sh b/tools/elftosb/test_elftosb.sh
new file mode 100755 (executable)
index 0000000..54bcde0
--- /dev/null
@@ -0,0 +1,26 @@
+#! /bin/bash
+
+# Tool paths
+if [ -d /System/Library/CoreServices ]; then
+    Elftosb=./build/Debug/elftosb
+    Sbtool=./build/Debug/sbtool
+else
+    Elftosb=./bld/linux/elftosb
+    Sbtool=./bld/linux/sbtool
+fi
+
+# Create test output file directory
+mkdir -p test_output
+
+# simple.e
+$Elftosb -Vdz -p bdfiles -p test_files -fmx28 -c simple.e -o test_output/output1.sb plugin_hello redboot_gcc.srec hostlink
+$Sbtool -Vdz test_output/output1.sb > test_output/output1.txt
+
+# habtest.bd
+$Elftosb -Vdz -p bdfiles -p test_files -fmx28 -c habtest.bd -o test_output/output2.sb plugin_hello redboot_gcc.srec hostlink
+$Sbtool -Vdz test_output/output2.sb > test_output/output2.txt
+
+# basic_test_cmd.e
+$Elftosb -Vdz -p bdfiles -p test_files -fmx28 -c basic_test_cmd.e -o test_output/output3.sb plugin_hello redboot_gcc.srec hostlink sd_player_gcc
+$Sbtool -Vdz test_output/output3.sb > test_output/output3.txt
+
diff --git a/tools/elftosb/test_files/hello_NOR_arm b/tools/elftosb/test_files/hello_NOR_arm
new file mode 100644 (file)
index 0000000..aef70bc
Binary files /dev/null and b/tools/elftosb/test_files/hello_NOR_arm differ
diff --git a/tools/elftosb/test_files/hello_NOR_arm.map b/tools/elftosb/test_files/hello_NOR_arm.map
new file mode 100644 (file)
index 0000000..65b4d14
--- /dev/null
@@ -0,0 +1,38 @@
+Link Date:     Wed Dec 15 10:06:16 2004\r
+Host OS:       GHS_WIN32\r
+Version:       ELXR 4.0 (c) 1998-2003 Green Hills Software    Build: Aug  3 2004\r
+\r
+\r
+Load Map Wed Dec 15 10:06:16 2004\r
+Image Summary\r
+\r
+  Section              Base      Size(hex)    Size(dec)  SecOffs\r
+  .text                70000000  00000100          256   00000a0\r
+  .rodata              70000100  00000020           32   00001a0\r
+  .NOR.data            70000120  00000000            0   00001c0\r
+  .data                00000040  00000000            0   00001c0\r
+  .bss                 00000040  00000000            0   00001c0\r
+  .nor.bss             0003d000  00000005            5   00001c0\r
+\f\r
+Load Map Wed Dec 15 10:06:16 2004\r
+Module Summary\r
+\r
+  Origin+Size    Section          Module\r
+70000000+000090  .text            main_NOR.o\r
+70000100+000020  .rodata          main_NOR.o\r
+0003d000+000005  .nor.bss         main_NOR.o\r
+70000090+000070  .text            tool_lib.a(sim_tools.o)\r
+\f\r
+Load Map Wed Dec 15 10:06:16 2004\r
+Global Symbols (sorted alphabetically)\r
+\r
+                  70002800 __ghs_norend\r
+                  70000000 __ghs_norstart\r
+                  0003cfc0 __ghs_ramend\r
+                  00000040 __ghs_ramstart\r
+ .text            70000000 _start\r
+ .nor.bss         0003d000 i\r
+ .text            70000090 sim_write\r
+ .nor.bss         0003d004 szHelloWorldString\r
+ .rodata          70000100 szNORHelloWorldString\r
+ .text            700000c0 test_exit\r
diff --git a/tools/elftosb/test_files/hello_NOR_mixed b/tools/elftosb/test_files/hello_NOR_mixed
new file mode 100644 (file)
index 0000000..7a7fb6b
Binary files /dev/null and b/tools/elftosb/test_files/hello_NOR_mixed differ
diff --git a/tools/elftosb/test_files/hello_NOR_mixed.map b/tools/elftosb/test_files/hello_NOR_mixed.map
new file mode 100644 (file)
index 0000000..c34358c
--- /dev/null
@@ -0,0 +1,39 @@
+Link Date:     Wed Dec 15 10:14:22 2004\r
+Host OS:       GHS_WIN32\r
+Version:       ELXR 4.0 (c) 1998-2003 Green Hills Software    Build: Aug  3 2004\r
+\r
+\r
+Load Map Wed Dec 15 10:14:22 2004\r
+Image Summary\r
+\r
+  Section              Base      Size(hex)    Size(dec)  SecOffs\r
+  .text                70000000  00000114          276   00000a0\r
+  .rodata              70000114  00000020           32   00001b4\r
+  .NOR.data            70000134  00000000            0   00001d4\r
+  .data                00000040  00000000            0   00001d4\r
+  .bss                 00000040  00000000            0   00001d4\r
+  .nor.bss             0003d000  00000005            5   00001d4\r
+\f\r
+Load Map Wed Dec 15 10:14:22 2004\r
+Module Summary\r
+\r
+  Origin+Size    Section          Module\r
+70000000+0000a4  .text            main_NOR.o\r
+70000114+000020  .rodata          main_NOR.o\r
+0003d000+000005  .nor.bss         main_NOR.o\r
+700000a4+000070  .text            tool_lib.a(sim_tools.o)\r
+\f\r
+Load Map Wed Dec 15 10:14:22 2004\r
+Global Symbols (sorted alphabetically)\r
+\r
+                  70002800 __ghs_norend\r
+                  70000000 __ghs_norstart\r
+                  0003cfc0 __ghs_ramend\r
+                  00000040 __ghs_ramstart\r
+ .text            70000014 _start\r
+ .text            70000000 a_thumb_routine\r
+ .nor.bss         0003d000 i\r
+ .text            700000a4 sim_write\r
+ .nor.bss         0003d004 szHelloWorldString\r
+ .rodata          70000114 szNORHelloWorldString\r
+ .text            700000d4 test_exit\r
diff --git a/tools/elftosb/test_files/hello_NOR_thumb b/tools/elftosb/test_files/hello_NOR_thumb
new file mode 100644 (file)
index 0000000..9c15fd3
Binary files /dev/null and b/tools/elftosb/test_files/hello_NOR_thumb differ
diff --git a/tools/elftosb/test_files/hello_NOR_thumb.map b/tools/elftosb/test_files/hello_NOR_thumb.map
new file mode 100644 (file)
index 0000000..3ba9f5d
--- /dev/null
@@ -0,0 +1,38 @@
+Link Date:     Wed Dec 15 10:09:42 2004\r
+Host OS:       GHS_WIN32\r
+Version:       ELXR 4.0 (c) 1998-2003 Green Hills Software    Build: Aug  3 2004\r
+\r
+\r
+Load Map Wed Dec 15 10:09:42 2004\r
+Image Summary\r
+\r
+  Section              Base      Size(hex)    Size(dec)  SecOffs\r
+  .text                70000000  000000a0          160   00000a0\r
+  .rodata              700000a0  00000020           32   0000140\r
+  .NOR.data            700000c0  00000000            0   0000160\r
+  .data                00000040  00000000            0   0000160\r
+  .bss                 00000040  00000000            0   0000160\r
+  .nor.bss             0003d000  00000005            5   0000160\r
+\f\r
+Load Map Wed Dec 15 10:09:42 2004\r
+Module Summary\r
+\r
+  Origin+Size    Section          Module\r
+70000000+00005c  .text            main_NOR.o\r
+700000a0+000020  .rodata          main_NOR.o\r
+0003d000+000005  .nor.bss         main_NOR.o\r
+7000005c+000044  .text            tool_lib.a(sim_tools.o)\r
+\f\r
+Load Map Wed Dec 15 10:09:42 2004\r
+Global Symbols (sorted alphabetically)\r
+\r
+                  70002800 __ghs_norend\r
+                  70000000 __ghs_norstart\r
+                  0003cfc0 __ghs_ramend\r
+                  00000040 __ghs_ramstart\r
+ .text            70000000 _start\r
+ .nor.bss         0003d000 i\r
+ .text            7000005c sim_write\r
+ .nor.bss         0003d004 szHelloWorldString\r
+ .rodata          700000a0 szNORHelloWorldString\r
+ .text            70000072 test_exit\r
diff --git a/tools/elftosb/test_files/hostlink b/tools/elftosb/test_files/hostlink
new file mode 100644 (file)
index 0000000..d2d7a94
Binary files /dev/null and b/tools/elftosb/test_files/hostlink differ
diff --git a/tools/elftosb/test_files/player_linfix.elf b/tools/elftosb/test_files/player_linfix.elf
new file mode 100644 (file)
index 0000000..9c66a01
Binary files /dev/null and b/tools/elftosb/test_files/player_linfix.elf differ
diff --git a/tools/elftosb/test_files/plugin_complex b/tools/elftosb/test_files/plugin_complex
new file mode 100644 (file)
index 0000000..10e2d7f
Binary files /dev/null and b/tools/elftosb/test_files/plugin_complex differ
diff --git a/tools/elftosb/test_files/plugin_hello b/tools/elftosb/test_files/plugin_hello
new file mode 100644 (file)
index 0000000..4b44083
Binary files /dev/null and b/tools/elftosb/test_files/plugin_hello differ
diff --git a/tools/elftosb/test_files/redboot_gcc.srec b/tools/elftosb/test_files/redboot_gcc.srec
new file mode 100644 (file)
index 0000000..0b74418
--- /dev/null
@@ -0,0 +1,3397 @@
+S02B00002F686F6D652F6376616E63652F32303035303530342F626C642F333630302F726564626F6F745F5276\r
+S21402600018F09FE518F09FE518F09FE518F09FE559\r
+S21402601018F09FE50000000018F09FE518F09FE5D5\r
+S214026020406002003C630200606302008C63020070\r
+S214026030A863020000000000CC640200886402002C\r
+S214026040100F11EE020AC0E30400C0E3010AC0E327\r
+S2140260500100C0E398159FE5010000E094159FE556\r
+S214026060010080E1100F01EE0000A0E10000A0E1B7\r
+S2140260700000A0E10000A0E10000A0E10000A0E115\r
+S2140260800000A0E10000A0E10000A0E3160F07EE6A\r
+S214026090150F07EE60059FE50311A0E3001080E5EB\r
+S2140260A058059FE50F16A0E3001080E550059FE512\r
+S2140260B00A16A0E3001080E548059FE548159FE50F\r
+S2140260C0001080E544059FE544159FE5001080E535\r
+S2140260D040059FE540159FE5001080E53C059FE5DD\r
+S2140260E03C159FE5001080E538059FE5031CA0E3FC\r
+S2140260F0001080E530059FE5011CA0E3001080E556\r
+S21402610028059FE50010E0E3001080E520059FE5E6\r
+S2140261100010E0E3001080E5E0049FE514159FE51B\r
+S214026120001080E510059FE50110A0E3001080E551\r
+S21402613008059FE50010A0E3001080E5FC049FE53B\r
+S2140261400410A0E3001080E5F4049FE50510A0E328\r
+S214026150001080E5EC049FE5EC149FE5001080E556\r
+S214026160E8049FE51316A0E3001080E5E0049FE52F\r
+S214026170D910A0E3001080E5D8049FE5D8149FE567\r
+S214026180001080E5D4049FE5011BA0E3001080E523\r
+S214026190CC049FE52310A0E3001080E5A201A0E353\r
+S2140261A0C0149FE5001080E5BC149FE5BC049FE583\r
+S2140261B0001080E5B8049FE5001080E5B4049FE572\r
+S2140261C0001080E5B0049FE5001080E5AC049FE572\r
+S2140261D0001080E5A8049FE5001080E5A4049FE572\r
+S2140261E0001080E5A0049FE5001080E59C049FE572\r
+S2140261F0001080E598049FE5001080E594049FE572\r
+S214026200001080E590049FE5001080E58C049FE571\r
+S214026210001080E588049FE5001080E584049FE571\r
+S214026220001080E580049FE5001080E59201A0E35F\r
+S2140262300318A0E3001080E570049FE50110A0E3B8\r
+S214026240001080E568049FE50010A0E3001080E5DA\r
+S214026250001080E50000A0E358149FE5082091E5B1\r
+S214026260082080E50000A0E368139FE5282091E55A\r
+S214026270282080E5182091E5182080E5382091E551\r
+S214026280382080E51C2091E51C2080E53C2091E525\r
+S2140262903C2080E50C2091E50C2080E52C2091E541\r
+S2140262A02C2080E5102091E5102080E5302091E535\r
+S2140262B0302080E5ECD29FE5D200A0E300F029E191\r
+S2140262C0E4D29FE5DB00A0E300F029E1D8D29FE507\r
+S2140262D0D300A0E300F029E100F069E1C4D29FE513\r
+S2140262E0CC129FE5CC229FE50000A0E3020051E11C\r
+S2140262F00200000A040081E4020051E1FCFFFF9A5A\r
+S214026300EC0A00EB4B1000EB0000A0E3A4139FE5A1\r
+S214026310042091E5042080E5242091E5242080E5F0\r
+S214026320031400EBD00A00EB531900EBFEFFFFEA62\r
+S2140263300000A0E300F0A0E10BB0ADDE6CD29FE55A\r
+S2140263403F002DE900104FE1200011E304004E0249\r
+S21402635002004E120120A0E30D30A0E1180000EA70\r
+S21402636000012DE944829FE53F0028E90830A0E1BC\r
+S2140263700001BDE800104FE1200011E304004E02C8\r
+S21402638002004E120220A0E30D0000EA1CD29FE596\r
+S2140263903F002DE904004EE200104FE10320A0E387\r
+S2140263A00D30A0E1060000EA00D29FE53F002DE98D\r
+S2140263B004004EE200104FE10420A0E30D30A0E1FD\r
+S2140263C0FFFFFFEA00400FE11F40C4E3134084E3EF\r
+S2140263D004F029E10D50A0E10E40A0E1C0D19FE5F6\r
+S2140263E00D0055E10200008AB0419FE5040055E128\r
+S2140263F005D0A08137002DE90D00A0E100200FE1B5\r
+S214026400C01081E32010C1E301F029E1007F20E9FA\r
+S21402641002F029E100D0A0E13F0093E8FF002DE959\r
+S21402642040109DE51F1001E2130051E34C109D053C\r
+S21402643034108D050D00A0E1660A00EB40009DE5D4\r
+S2140264401F1000E2130051E300F069E1FFFFDD08D0\r
+S21402645020208DE200100FE1C00080E32000C0E3A0\r
+S21402646000F029E1007F92E801F029E14C009DE569\r
+S21402647020008DE548009DE524008DE53C009DE565\r
+S21402648028008DE5FFE0DDE80180A0E328929FE585\r
+S214026490008089E500804FE11F9008E2120059E370\r
+S2140264A00200001A408088E308F069E104F05EE228\r
+S2140264B0F4D09FE500410DE9D280A0E308F029E17F\r
+S2140264C0E4D09FE500601DE90DF069E1D8D09FE5B4\r
+S2140264D03F002DE904004EE200104FE10620A0E343\r
+S2140264E00D30A0E100400FE11F40C4E3134084E3F7\r
+S2140264F004F029E10D50A0E10E40A0E137002DE99D\r
+S2140265000D00A0E100200FE1C01081E32010C1E3DE\r
+S21402651001F029E1007F20E902F029E100D0A0E1A4\r
+S2140265203F0093E8FF002DE940109DE51F1001E2B1\r
+S214026530130051E34C109D0534108D050D90A0E11B\r
+S2140265400900A0E1B00A00EB0040A0E10400A0E1CF\r
+S21402655068219FE5009082E5010070E30200001AC0\r
+S2140265600900A0E13D0A00EB060000EA5C109FE588\r
+S214026570041191E750209FE5046192E70920A0E10B\r
+S2140265800FE0A0E106F0A0E1ABFFFFEA0EF0A0E10B\r
+S21402659000000FE10EF0A0E10D00A0E10EF0A0E178\r
+S2140265A0203503002045030020550300A0340300D5\r
+S2140265B0203503001C340300048503000485030011\r
+S2140265C0C02D0300C02D03001C340300C42D03009D\r
+S2140265D0C82E0300CC2F030000600200C02D03006B\r
+S2140265E065436F73203A20004D61792020392032AE\r
+S2140265F030303500FFF30500780005000880018082\r
+S2140266001883018014830180188001800000FFFF38\r
+S214026610148001800000555528800180C0F00300D8\r
+S214026620248001804050010028810180248101805D\r
+S2140266301882018028820180FFFF0F00B0000480CC\r
+S214026640000002800001028010010280070707078F\r
+S21402665090000280A0000280C0000280F83333332C\r
+S214026660D0000280B0000280000003C00F0F0F0FA0\r
+S2140266706800008078000080880000809800008013\r
+S214026680A8000080B8000080C8000080D800008003\r
+S214026690E8000080F80000800801008018010080F1\r
+S2140266A028010080380100804801008058010080DF\r
+S2140266B00880038000C0018000600200C031030031\r
+S2140266C0E08203000DC0A0E130D82DE9E4409FE54A\r
+S2140266D004B04CE20C5194E5000055E30A0000BAFF\r
+S2140266E01800001A183194E5000053E32600001A39\r
+S2140266F0C0409FE5103194E5FF0053E3070000CA4F\r
+S214026700183194E5000053E30100001A0000E0E3AC\r
+S21402671030A81BE9A0009FE5071700EBFAFFFFEA87\r
+S214026720080084E2452F84E2080184E5011CA0E308\r
+S2140267300FE0A0E104F094E5000050E3100184E5C8\r
+S2140267400C0184E5070000DA68109FE50C3191E53C\r
+S214026750082191E5013043E20C3181E50100D2E4E3\r
+S214026760082181E530A81BE9E4FFFFAA140194E59D\r
+S214026770003094E50FE0A0E110F093E50010A0E1F0\r
+S21402678038009FE5EC1600EBDCFFFFEA202194E5DB\r
+S2140267902C309FE52C009FE50310D2E7012082E211\r
+S2140267A0202184E5E41600EB203194E5060053E34D\r
+S2140267B020518485CDFFFFEAC06F030080230300CB\r
+S2140267C0401603009C310300501603000DC0A0E1E2\r
+S2140267D0F0DD2DE97C509FE50140A0E104B04CE2DB\r
+S2140267E00510A0E10260A0E10370A0E100A0A0E114\r
+S2140267F00FE0A0E100F094E50080A0E10000A0E335\r
+S214026800000058E1451F45E2090000BA0C2094E555\r
+S214026810013CA0E3144105E5103181E5186181E5EC\r
+S2140268201C7181E5200181E50C0181E5042081E5EA\r
+S214026830F0AD1BE9000095E50FE0A0E110F094E54D\r
+S21402684000109AE50020A0E10C009FE5BA1600EBC6\r
+S2140268500800A0E1F0AD1BE9D47003005416030053\r
+S21402686010309FE5102193E5081083E20C2183E5A2\r
+S214026870081183E50EF0A0E1C06F03000DC0A0E191\r
+S21402688000D82DE920309FE504B04CE2002093E5C5\r
+S21402689018109FE5083092E5000053E300A81B0994\r
+S2140268A00FE0A0E103F0A0E100A81BE9C06F03001F\r
+S2140268B0C46602000DC0A0E100D82DE914309FE5A1\r
+S2140268C004B04CE2450F83E2002093E50FE0A0E11E\r
+S2140268D004F092E500A81BE9C06F03000DC0A0E11A\r
+S2140268E0000052E3F0D82DE904B04CE20070A0E1BB\r
+S2140268F00150A0E10060A0E3014042E2090000DA94\r
+S2140269000FE0A0E107F0A0E1000050E30430A0E1B0\r
+S214026910014044E2030000BA000053E30100C5E46C\r
+S214026920016086E2F5FFFFCA0600A0E1F0A81BE9B7\r
+S2140269300DC0A0E1F0DF2DE904B04CE251DF4DE2DC\r
+S2140269403420A0E30090A0E160110BE55C104BE25E\r
+S214026950E1FFFFEB00A0A0E3340050E30010E0E309\r
+S21402696064A10BE568110BE5F8029F150200000A08\r
+S214026970711600EB0A00A0E1F0AF1BE9BC345BE144\r
+S2140269800080A0E1020053E3DC029F15F7FFFF1A26\r
+S214026990B0235BE1080052E3B000008A40301BE5FA\r
+S2140269A0030050E1A300003A0070A0E30238A0E121\r
+S2140269B0230857E10C0000AA574F4BE20410A0E14F\r
+S2140269C00900A0E12020A0E3C3FFFFEB200050E374\r
+S2140269D0017087E2208088E2204084E29300001A59\r
+S2140269E0B0235BE1020057E1F3FFFFBA60311BE51B\r
+S2140269F0000053E360A11B050D00000A0238A0E167\r
+S214026A002338B0E100A0E0E30700000A0370A0E12B\r
+S214026A1028104BE2343111E5010053E37F00000AEF\r
+S214026A20017057E2201081E2F9FFFF1A60111BE5A0\r
+S214026A3001A06AE00070A0E30238A0E1230857E153\r
+S214026A400C0000AA28304BE26C310BE56C111BE5FA\r
+S214026A50343111E5010053E33000000A0238A0E1A8\r
+S214026A60017087E2230857E16C311BE5203083E290\r
+S214026A706C310BE5F4FFFFBA60111BE5000051E331\r
+S214026A801C00000A68111BE564311BE5DC619FE50A\r
+S214026A90032061E044301BE5D4519FE5033061E0FA\r
+S214026AA060111BE5CC419FE5033081E0022081E0C6\r
+S214026AB0002085E5003084E5001086E50000A0E3AE\r
+S214026AC06DFFFFEB00005AE30600001A001094E583\r
+S214026AD0002096E5003095E59C019FE5161600EB32\r
+S214026AE00100A0E3F0AF1BE90A10A0E18C019FE5CC\r
+S214026AF0111600EBF4FFFFEA68311BE56C619FE5B7\r
+S214026B006C519FE56C419FE5003086E564111BE5FC\r
+S214026B1044301BE5001085E5003084E5E6FFFFEA19\r
+S214026B20284111E568311BE5302111E5040053E1E7\r
+S214026B300430A021020058E168310BE5245111E52A\r
+S214026B400A4084E02A00009A053082E0080053E1F9\r
+S214026B5008306220034084202300003A000055E3F8\r
+S214026B60015045E2130000DA0400A0E13E1900EBF2\r
+S214026B70000050E30060A0E1018088E21300000AF2\r
+S214026B800FE0A0E109F0A0E1000050E30520A0E13B\r
+S214026B90015045E2090000BA0100C4E464111BE595\r
+S214026BA004306AE0030051E10310A031000052E312\r
+S214026BB064110BE5EBFFFFCAB0235BE1A6FFFFEA19\r
+S214026BC0BC009FE5DC1500EB0000A0E3F0AF1BE97C\r
+S214026BD00100A0E328FFFFEB0410A0E1A4009FE55C\r
+S214026BE0D51500EB0600A0E1F0AF1BE998009FE583\r
+S214026BF0F3FFFFEAD8FFFF2A6C611BE50FE0A0E176\r
+S214026C0009F0A0E1000050E3018088E2EBFFFFBA42\r
+S214026C10303116E5030058E1F7FFFF3ACEFFFFEAF0\r
+S214026C20283111E503005AE103A0A0217BFFFFEA09\r
+S214026C3058009FE5E2FFFFEA0FE0A0E109F0A0E1BD\r
+S214026C40000050E3018088E2DCFFFFBA40301BE51B\r
+S214026C50030058E1F7FFFF3AB0235BE151FFFFEA7A\r
+S214026C602C009FE541FFFFEA6C1603008416030022\r
+S214026C70E0840300A083030040840300A8160300F8\r
+S214026C80D0160300E8160300041703004C1703008F\r
+S214026C9080170300A01703000DC0A0E1000051E317\r
+S214026CA0F0D92DE904B04CE20080A0E10260A0E138\r
+S214026CB00070A0E3015041E2440000DA0FE0A0E1D8\r
+S214026CC008F0A0E1FF4000E20FE0A0E108F0A0E13A\r
+S214026CD041C044E2302044E2FF300CE2050053E3B8\r
+S214026CE009005283FF0000E20020A0E30200009A9F\r
+S214026CF0613044E2050053E30000008A0120A0E36D\r
+S214026D00000052E33300000A41E040E2302040E255\r
+S214026D10FF300EE2050053E3090052830020A0E391\r
+S214026D200200009A613040E2050053E30000008A48\r
+S214026D300120A0E3000052E32600000A302044E2CD\r
+S214026D40FF3002E2090053E30010A0E30774A0E15B\r
+S214026D500210A0910600009A613044E2050053E357\r
+S214026D60571044920200009AFF300CE2050053E3EB\r
+S214026D7037104492302040E2FF3002E2090053E32B\r
+S214026D8001C2A0E10010A0E30210A0910600009A42\r
+S214026D90613040E2050053E3571040920200009A29\r
+S214026DA0FF300EE2050053E337104092000056E330\r
+S214026DB00030961501208CE102308310027087E1C4\r
+S214026DC000308615000055E3015045E2BAFFFFCABF\r
+S214026DD00700A0E1F0A91BE90000E0E3F0A91BE927\r
+S214026DE00DC0A0E1F0DF2DE904B04CE20080A0E384\r
+S214026DF01CD04DE20060A0E10100A0E330100BE5DC\r
+S214026E000010E0E338000BE53C800BE540800BE524\r
+S214026E1044100BE50FE0A0E106F0A0E1000050E30D\r
+S214026E200040A0E1690000DA530054E3AC00001A07\r
+S214026E300FE0A0E106F0A0E128A04BE20050A0E39C\r
+S214026E4004502AE50030A0E10110A0E30600A0E10C\r
+S214026E500A20A0E1FF7003E28EFFFFEB050050E17F\r
+S214026E600040A0E1028088E2960000BA303047E295\r
+S214026E70018088E2090053E303F19F975C0000EA71\r
+S214026E809C6F0200A86E0200A86E0200A86E0200A6\r
+S214026E90F46F0200F46F0200F46F0200107002003A\r
+S214026EA010700200107002000A20A0E12F1047E2C4\r
+S214026EB00600A0E177FFFFEB38201BE5073088E0ED\r
+S214026EC0000052E30050A0E12F8043E234000BE5BD\r
+S214026ED00700000A30301BE50020A0E3000053E361\r
+S214026EE030101B05030060103C000B153C100B0510\r
+S214026EF038200BE53C301BE544101BE5035085E0CB\r
+S214026F00053063E0030051E10310A0210500A0E173\r
+S214026F1044100BE5541800EB000050E30090A0E18B\r
+S214026F202C00000A042067E02E4082E2000054E3B0\r
+S214026F30048088E02D4082E2070000DA0600A0E125\r
+S214026F400110A0E30A20A0E152FFFFEB000054E389\r
+S214026F500100C5E4014044E2F7FFFFCA0020A0E3B7\r
+S214026F600600A0E10110A0E34AFFFFEB2C205BE540\r
+S214026F700030E0E1FF4003E2020054E12C200BE582\r
+S214026F80018088E20A00001A3C201BE540301BE51F\r
+S214026F90050062E0030050E140000B850FE0A0E12F\r
+S214026FA006F0A0E10A0050E399FFFF0A018088E29A\r
+S214026FB0F9FFFFEA0100A0E32FFEFFEB34101BE50A\r
+S214026FC02C201BE50430A0E12C019FE5DA1400EB2F\r
+S214026FD00000A0E3F0AF1BE90100A0E326FEFFEBF2\r
+S214026FE00510A0E114019FE5D31400EB0900A0E10F\r
+S214026FF0F0AF1BE90100A0E31FFEFFEB00019FE5D7\r
+S2140270000810A0E10720A0E1CB1400EBEFFFFFEA97\r
+S2140270103B1067E20600A0E10A20A0E11DFFFFEB9D\r
+S2140270200050A0E130001BE5000050E31C00000AFF\r
+S21402703044101BE540001BE5052061E0003061E0DE\r
+S21402704030101BE5BC709FE5BC609FE5BC409FE529\r
+S214027050012082E0033081E0003086E5002084E5EE\r
+S214027060001087E50000A0E303FEFFEB3C001BE5F3\r
+S214027070000050E30600001A001094E5002097E591\r
+S214027080003096E588009FE5AB1400EB000096E51D\r
+S214027090F0AF1BE90010A0E178009FE5A61400EB14\r
+S2140270A0F4FFFFEA5C709FE55C609FE55C409FE54D\r
+S2140270B044201BE540301BE5002087E5003086E5CE\r
+S2140270C0005084E5E6FFFFEA0100A0E3EAFDFFEBDD\r
+S2140270D00810A0E140009FE5971400EB0500A0E130\r
+S2140270E0F0AF1BE90100A0E3E3FDFFEB2C009FE5F8\r
+S2140270F00810A0E10420A0E1C2FFFFEABC170300CB\r
+S214027100F817030044180300E0840300A08303007A\r
+S21402711040840300A8160300D0160300701803006C\r
+S214027120941803000DC0A0E1F0DD2DE904B04CE296\r
+S2140271300040A0E3DCE39FE5D0504BE2E4D04DE212\r
+S2140271400060A0E10420A0E1E0C04BE20170A0E1F3\r
+S2140271500500A0E17610A0E30230A0E300C08DE5B2\r
+S21402716008E08DE5E8400BE5F8400BE504408DE5C8\r
+S2140271708A1C00EBA0E39FE50420A0E1E4C04BE2FA\r
+S214027180B8004BE27210A0E30230A0E300C08DE527\r
+S21402719010408DE9811C00EBE8C04BE200C08DE593\r
+S2140271A078C39FE50430A0E1ECE04BE2A0004BE29E\r
+S2140271B06210A0E30120A0E304E08DE508C08DE59F\r
+S2140271C0761C00EBF0C04BE20120A0E300C08DE588\r
+S2140271D04CC39FE50230A0E1F4E04BE288004BE2AC\r
+S2140271E06D10A0E304E08DE508C08DE56B1C00EB96\r
+S2140271F004C0A0E30480A0E100C08DE504A0A0E1E5\r
+S21402720020C39FE5014084E20600A0E1F8E04BE2DD\r
+S2140272100710A0E10420A0E10530A0E104E08DE51E\r
+S2140272200CC08DE508408DE5651C00EB080050E1BA\r
+S2140272300860A0E1F0AD1B09F4301BE5080053E13D\r
+S214027240B200000AE0429FE5E0329FE50450A0E16A\r
+S214027250030054E10C00000AF0001BE5941E00EB4C\r
+S214027260001094E50020A0E1F0001BE5A21700EB59\r
+S214027270000050E304A094050300000AAC329FE528\r
+S214027280144084E2030054E1F2FFFF1A00005AE3BE\r
+S2140272908B00000A083094E50C1094E5E0201BE50C\r
+S2140272A0000051E3032002E0E0200BE50200000AA2\r
+S2140272B0F8301BE5000053E37B00000AEC301BE5C8\r
+S2140272C0000053E36D00001AE4301BE5000053E3B0\r
+S2140272D00200000AEC301BE5000053E36400000ADB\r
+S2140272E0F8201BE50030E0E3000054E3D4300BE561\r
+S2140272F0DC200BE510C094155B00000ADC004BE2B4\r
+S2140273000A10A0E1E0201BE50030A0E3D8C00BE5A0\r
+S2140273102DFDFFEB000050E30050A0E1F0AD1BB9DD\r
+S214027320E4301BE5000053E3E8401B150070A01391\r
+S2140273302900001A0360A0E124404BE2E0FCFFEBC8\r
+S214027340000050E3016086E20050A0E1030000BAAC\r
+S214027350030056E3040044E5014084E2F6FFFF9A88\r
+S214027360000055E30E0000BA3CFDFFEB27004BE29F\r
+S214027370BC119FE50320A0E3E61D00EB000050E3EE\r
+S2140273801100000A28305BE5530053E30600000AAA\r
+S2140273900100A0E338FDFFEB98019FE528101BE5EE\r
+S2140273A0E51300EB42FDFFEBF0AD1BE927305BE592\r
+S2140273B0303043E2090053E3F4FFFF8AE8101BE58E\r
+S2140273C074019FE585FEFFEBF5FFFFEAE8101BE57B\r
+S2140273D064019FE555FDFFEBF1FFFFEAB8FCFFEB0A\r
+S2140273E00050A0E1000055E30400A0E10C0000BA42\r
+S2140273F01D1700EB000050E30100001A000056E3E0\r
+S2140274000100000A0150C4E4F3FFFFEA0100A0E312\r
+S21402741019FDFFEB0410A0E120019FE5C61300EB67\r
+S2140274200070E0E3E8101BE514319FE514219FE5A8\r
+S214027430001083E510319FE50000A0E3001082E50E\r
+S214027440004083E50CFDFFEB000057E30480A0E15B\r
+S214027450D3FFFF1AE8101BE5012044E20130A0E149\r
+S214027460E8009FE5B41300EBCDFFFFEA04C0A0E1FD\r
+S214027470A1FFFFEAD8009FE5AF1300EBF0AD1BE9D2\r
+S214027480E8001BE5F81600EB000050E38DFFFF1A3C\r
+S214027490E8101BE5BC009FE5831A00EB000050E3F2\r
+S2140274A0F0AD1B090160A0E386FFFFEAA8009FE596\r
+S2140274B0A11300EBA4109FE5A4009FE59E1300EB2A\r
+S2140274C0F0AD1BE9F0101BE598009FE59A1300EB60\r
+S2140274D058309FE50540A0E1030055E10600000A8A\r
+S2140274E00350A0E1001094E57C009FE5144084E27E\r
+S2140274F0911300EB050054E1F9FFFF1A6C009FE5BB\r
+S2140275008D1300EB00005AE361FFFF1AF0AD1BE992\r
+S2140275105C009FE5D7FFFFEAC0180300C818030007\r
+S214027520D8180300E818030010190300F03303000C\r
+S214027530183403001C19030020190300C466020055\r
+S2140275404019030040840300E0840300A083030084\r
+S2140275507C190300A8190300CC190300001A0300C3\r
+S2140275604C310300141A0300241A03007C2503007E\r
+S214027570802303004C1A03000DC0A0E110D82DE9A9\r
+S21402758028409FE504B04CE204D04DE2003094E57A\r
+S21402759011104BE2000093E51C2093E50FE0A0E1FA\r
+S2140275A002F0A0E1000050E310A81B09F6FFFFEA74\r
+S2140275B0205503000DC0A0E1F0D82DE954639FE5E5\r
+S2140275C004B04CE204D04DE20050A0E3303496E51D\r
+S2140275D00570A0E1050053E10540A0E1C500001AD0\r
+S2140275E01D604BE22C339FE50610A0E1002093E5D8\r
+S2140275F0014084E2000092E51C3092E50FE0A0E133\r
+S21402760003F0A0E1000050E3B300000A1D105BE5A2\r
+S214027610013041E2170053E303F19F97210000EA8D\r
+S2140276208076020090760200A87602008C7802002D\r
+S214027630A8760200A8760200A8760200A8760200C3\r
+S214027640A8760200A8760200A8760200A8760200B3\r
+S214027650A8760200A8760200A8760200A8760200A3\r
+S214027660A8760200A8760200A8760200A876020093\r
+S214027670A8760200A8760200A8760200B878020071\r
+S21402768090229FE51C3492E5013083E21C3482E5A9\r
+S21402769080229FE5020051E3203492050150A0E3C8\r
+S2140276A00530830020348205000055E3CCFFFF0A34\r
+S2140276B060429FE5003094E5011B84E2000093E5FA\r
+S2140276C0081081E21C2093E50FE0A0E102F0A0E1A1\r
+S2140276D0000050E30100001A0200E0E3F0A81BE9F4\r
+S2140276E0003094E5011B84E2000093E5091081E274\r
+S2140276F01C2093E50FE0A0E102F0A0E1000050E3B9\r
+S214027700F4FFFF0A1D205BE50050A0E3010052E3F0\r
+S214027710012BA0138020A003043084E2020055E16E\r
+S214027720043484E5102484E50E0000AA003094E5B3\r
+S2140277300610A0E1000093E51C2093E50FE0A0E10F\r
+S21402774002F0A0E1000050E3041085E0015085E25B\r
+S214027750E0FFFF0A103494E51D205BE5030055E1C7\r
+S2140277600420C1E5F0FFFFBAA8419FE5003094E58A\r
+S214027770011B84E2000093E50A1081E21C2093E5D7\r
+S2140277800FE0A0E102F0A0E1000050E3D1FFFF0A03\r
+S214027790283494E5000053E33100001A74419FE553\r
+S2140277A074319FE574119FE50320D4E70130D4E7D6\r
+S2140277B0032022E0FF0052E30200000A6DFFFFEB07\r
+S2140277C00500E0E3F0A81BE9280494E5000050E376\r
+S2140277D01700001A103494E50050A0E1030050E1AF\r
+S2140277E0090000AA04C0A0E10310A0E10C2085E075\r
+S2140277F00430D2E5015085E2003083E00338A0E190\r
+S214027800010055E14308A0E1F7FFFFBA04119FE526\r
+S2140278100C319FE5FF0000E20320D1E7000052E1B1\r
+S2140278200100000A0600E0E3F0A81BE90000A0E35E\r
+S214027830F0A81BE9101494E5040084E2B61D00EBE0\r
+S214027840DC309FE5DC209FE50310D4E70230D4E766\r
+S2140278500008A0E1013483E1200853E1F2FFFF0AA9\r
+S214027860EFFFFFEA003094E5011B84E2000093E597\r
+S2140278700B1081E21C2093E50FE0A0E102F0A0E1EC\r
+S214027880000050E393FFFF0AC3FFFFEA010054E340\r
+S21402789084FFFF1A7C309FE50610A0E3002093E5E4\r
+S2140278A0000092E50C3092E50FE0A0E103F0A0E1C3\r
+S2140278B00300E0E3F0A81BE958209FE5017087E289\r
+S2140278C0243492E5030057E3013083E2243482E550\r
+S2140278D00400E003F0A81B0972FFFFEA25FFFFEB96\r
+S2140278E044309FE544009FE5482093E50FE0A0E181\r
+S2140278F002F0A0E177FFFFEA003096E50610A0E36B\r
+S214027900000093E50C2093E50FE0A0E102F0A0E171\r
+S214027910305486E531FFFFEA2055030008040000D4\r
+S214027920090400000A0400000B04000050000000D6\r
+S21402793090D003000DC0A0E1F0D92DE978419FE573\r
+S21402794004B04CE2343094E50060A0E10000E0E3CD\r
+S2140279500180A0E10FE0A0E103F0A0E1082096E597\r
+S2140279600050A0E1000052E3343094A5343094B5C0\r
+S2140279700200A0A10FE0A0E103F0A0E138119FE50C\r
+S21402798038419FE5142091E50500A0E1343091E5E9\r
+S214027990002084E50FE0A0E103F0A0E1002094E5DA\r
+S2140279A00710A0E3000092E514C092E57D2EA0E346\r
+S2140279B00FE0A0E10CF0A0E10030A0E30120A0E37C\r
+S2140279C0282484E5103484E52C3484E5303484E5B8\r
+S2140279D0042096E50A70A0E3243484E5142484E5A2\r
+S2140279E0183484E51C3484E5203484E50460A0E180\r
+S2140279F01350A0E3EEFEFFEB0040A0E1000054E3CC\r
+S214027A00BC009FE52000000A030074E30800000A99\r
+S214027A10050074E30530A0E1015045E20100000ACA\r
+S214027A20000053E3F2FFFFCA0000E0E3004088E5EF\r
+S214027A30F0A91BE9017047E2000057E37C309FD5AE\r
+S214027A400020A0D3282483D56C309FE5482093E5F8\r
+S214027A500FE0A0E102F0A0E1281496E5003096E5DA\r
+S214027A60000051E3000093E51510A0030C2093E5F7\r
+S214027A704310A0130FE0A0E102F0A0E1183496E54F\r
+S214027A80013083E2183486E5E0FFFFEA2C109FE51A\r
+S214027A9030309FE50400A0E10320D1E7104481E5E1\r
+S214027AA0000052E30130A0033034810518309FE510\r
+S214027AB00120A0E30320C1E7F0A91BE95000000063\r
+S214027AC02055030020A10700080400000C04000053\r
+S214027AD00DC0A0E1F0DF2DE904B04CE2A0C29FE5A4\r
+S214027AE00170A0E12C149CE5000057E30030A0D3FF\r
+S214027AF00130A0C3000051E30030A013013003029E\r
+S214027B00000053E30080A0E10290A0E100A0A0E301\r
+S214027B104000000A10349CE5000053E33000001ACF\r
+S214027B205C529FE51360A0E3A1FEFFEB50C29FE507\r
+S214027B300040A0E1000054E30C00A0E144E29FE50F\r
+S214027B400E00001A40329FE50610A0E30320DCE791\r
+S214027B500E30DCE7030052E16B00000A24329FE598\r
+S214027B6024229FE50300DCE70230DCE7010040E266\r
+S214027B70FF0000E2000053E10740E0135C00000A49\r
+S214027B80050074E31000000A040074E33500000ADE\r
+S214027B90281495E5003095E5000051E3000093E5D2\r
+S214027BA01510A0030C2093E54310A0130FE0A0E1EC\r
+S214027BB002F0A0E1183495E5013083E2183485E539\r
+S214027BC0000056E3016046E2D6FFFFCA000054E317\r
+S214027BD0AC319FB50020E0B3004089B5102483B5D0\r
+S214027BE00C0000BA98519FE52C1495E5000051E36D\r
+S214027BF00A00000A000057E30030A0D30130A0C3F9\r
+S214027C00000051E30030A01301300302000053E3EA\r
+S214027C1005C0A0E1BEFFFF1A0A00A0E1F0AF1BE913\r
+S214027C20104495E5041495E5070054E10740A0A129\r
+S214027C300800A0E10420A0E1951200EB103495E5BF\r
+S214027C40042495E5033064E0042082E02C1495E5D4\r
+S214027C50103485E5042485E5077064E0048088E036\r
+S214027C6004A08AE0E2FFFFEA14519FE50660A0E363\r
+S214027C70003095E50610A0E1000093E50C2093E5A0\r
+S214027C800FE0A0E102F0A0E1143495E5020053E310\r
+S214027C900200000A0130A0E32C3485E5CAFFFFEAA1\r
+S214027CA0281495E5003095E5000051E3000093E5C1\r
+S214027CB01510A0030C2093E54310A0130FE0A0E1DB\r
+S214027CC002F0A0E1183495E5013083E2183485E528\r
+S214027CD037FEFFEB003095E50040A0E10610A0E17C\r
+S214027CE0000093E50C2093E50FE0A0E102F0A0E18E\r
+S214027CF0E7FFFFEA00309CE5000093E50C2093E5E1\r
+S214027D000FE0A0E102F0A0E1ACFFFFEA04149CE55C\r
+S214027D1010C49CE5013083E20120A0E30E30C0E7E8\r
+S214027D20302480E50C1081E0013051E51A0053E35F\r
+S214027D30A5FFFF1A023051E51A0053E3A2FFFF1A0D\r
+S214027D40033051E51A0053E39FFFFF1A00005CE37D\r
+S214027D509DFFFF0A0010A0E1103491E5012043E2E6\r
+S214027D60000052E3102481E597FFFF0A043491E5F0\r
+S214027D70023083E0012053E51A0052E3F5FFFF0AC2\r
+S214027D8091FFFFEA205503000C04000008040000DF\r
+S214027D900DC0A0E110D82DE904B04CE238C09FE532\r
+S214027DA008D04DE234009FE528E49CE518449CE5A3\r
+S214027DB000005EE324E49CE524109FE51C249CE579\r
+S214027DC00010A01120349CE518009FE500E08DE528\r
+S214027DD004408DE5581100EB10A81BE9205503005E\r
+S214027DE0641A0300681A0300701A03000DC0A0E1AB\r
+S214027DF0000050E330D82DE904B04CE20140A0E187\r
+S214027E003A00000A0C519FE5143495E5013043E22E\r
+S214027E10010053E330A81B89003095E51840A0E323\r
+S214027E20000093E50410A0E10C2093E50FE0A0E12A\r
+S214027E3002F0A0E1003095E50410A0E1000093E511\r
+S214027E400C2093E50FE0A0E102F0A0E1003095E5FA\r
+S214027E500410A0E1000093E50C2093E50FE0A0E1FA\r
+S214027E6002F0A0E1003095E50410A0E1000093E5E1\r
+S214027E700C2093E50FE0A0E102F0A0E1003095E5CA\r
+S214027E80104044E2000093E50410A0E10C2093E5C4\r
+S214027E900FE0A0E102F0A0E1003095E50410A0E1B9\r
+S214027EA0000093E50C2093E50FE0A0E102F0A0E1CC\r
+S214027EB0003095E50410A0E1000093E50C2093E560\r
+S214027EC00FE0A0E102F0A0E1003095E50410A0E189\r
+S214027ED0000093E50C2093E50FE0A0E102F0A0E19C\r
+S214027EE0A4FDFFEB0130A0E32C3485E530A81BE9A6\r
+S214027EF00FE0A0E104F0A0E1010070E3FBFFFFCA7F\r
+S214027F0014309FE514009FE5482093E50FE0A0E1BA\r
+S214027F1002F0A0E130A81BE9205503005000000043\r
+S214027F2090D00300080080E2070050E300F19F971C\r
+S214027F30090000EA647F02006C7F0200747F020080\r
+S214027F407C7F0200847F02008C7F0200947F020006\r
+S214027F50547F020040009FE50EF0A0E13C009FE542\r
+S214027F600EF0A0E138009FE50EF0A0E134009FE598\r
+S214027F700EF0A0E130009FE50EF0A0E12C009FE598\r
+S214027F800EF0A0E128009FE50EF0A0E124009FE598\r
+S214027F900EF0A0E120009FE50EF0A0E1B41A030067\r
+S214027FA0C81A0300D81A0300F01A0300041B0300C1\r
+S214027FB0141B0300201B03002C1B0300381B0300AA\r
+S214027FC00DC0A0E170D82DE904B04CE250D04DE2CD\r
+S214027FD04CC04BE248404BE200C08DE52CC19FE509\r
+S214027FE050E04BE20060A0E10150A0E10400A0E1F5\r
+S214027FF06210A0E30120A0E30030A0E304E08DE5D8\r
+S21402800008C08DE5E51800EB54C04BE200C08DE5D4\r
+S214028010FCC09FE558E04BE230004BE26C10A0E358\r
+S2140280200120A0E30030A0E304E08DE508C08DE562\r
+S214028030DA1800EB02C0A0E300C08DE5D4C09FE5CD\r
+S2140280400430A0E10510A0E10040A0E30600A0E194\r
+S2140280500120A0E308408DE50CC08DE504408DE5C7\r
+S214028060D71800EB040050E170A81B0950301BE53E\r
+S214028070A4009FE5040053E10200000A58301BE505\r
+S214028080040053E11600001A90309FE590209FE509\r
+S21402809000E093E5003092E503005EE10A00003A54\r
+S2140280A080309FE580209FE500C093E5003092E592\r
+S2140280B003005CE10400002A0C005EE10E10A0E161\r
+S2140280C00C20A0E10C306EE00100003A9A1000EBA2\r
+S2140280D070A81BE954009FE554300BE54CE00BE515\r
+S2140280E0951000EB54101BE54C001BE5711B00EBD2\r
+S2140280F054C01BE50010A0E10C20A0E10130A0E175\r
+S2140281002C009FE500C08DE58B1000EB70A81BE9E4\r
+S214028110441C0300541C0300681B03006C1B030072\r
+S214028120E084030000840300A0830300408303006E\r
+S214028130901B0300B01B03000DC0A0E1F0D82DE990\r
+S21402814004B04CE2C4D04DE2B0C04BE2AC504BE2BD\r
+S21402815000C08DE520C29FE5B4E04BE20060A0E1DE\r
+S2140281600170A0E10500A0E16210A0E30120A0E3F7\r
+S2140281700030A0E304E08DE508C08DE5871800EB2B\r
+S214028180B8C04BE200C08DE5F0C19FE5BCE04BE213\r
+S21402819094004BE26C10A0E30120A0E30030A0E3C1\r
+S2140281A004E08DE508C08DE57C1800EBC0C04BE20C\r
+S2140281B000C08DE5C8C19FE5C4E04BE27C004BE2FF\r
+S2140281C07010A0E30120A0E30030A0E30040A0E38B\r
+S2140281D004E08DE508C08DE5701800EBA4E19FE58C\r
+S2140281E0C8C04BE264004BE23410A0E30420A0E1D6\r
+S2140281F00230A0E300C08DE510408DE9671800EB61\r
+S21402820084E19FE5CCC04BE24C004BE23210A0E387\r
+S2140282100420A0E10230A0E300C08DE510408DE905\r
+S2140282205E1800EB64E19FE5D0C04BE234004BE2FF\r
+S2140282303110A0E30420A0E10230A0E300C08DE5E7\r
+S21402824010408DE9551800EB06C0A0E300C08DE58E\r
+S2140282503CC19FE50600A0E10710A0E10530A0E1C1\r
+S2140282600120A0E308408DE50CC08DE504408DE5B5\r
+S214028270531800EB040050E1F0A81B09B4301BE5CC\r
+S214028280040053E10200000ABC301BE5040053E17F\r
+S2140282900200001AFC009FE5271000EBF0A81BE97D\r
+S2140282A0C4301BE5000053E3C0300B05D0301BE59D\r
+S2140282B0000053E30F00000AB8301BE5013043E22A\r
+S2140282C0000053E3B8300BE5F0A81BB9B0101BE56D\r
+S2140282D0C0205BE5013081E2B0300BE50020C1E54D\r
+S2140282E0B8301BE5013043E2000053E3B8300BE53B\r
+S2140282F0F0A81BB9F4FFFFEACC301BE5000053E3FD\r
+S2140283000F00000AB8301BE5023043E2000053E3D8\r
+S214028310B8300BE5F0A81BB9B00C5BE1B8201BE542\r
+S214028320B0101BE5022042E2023081E2000052E376\r
+S214028330B0300BE5B000C1E1B8200BE5F0A81BB9E0\r
+S214028340F5FFFFEAB8301BE5043043E2000053E3D2\r
+S214028350B8300BE5F0A81BB9C0001BE5B0101BE552\r
+S2140283600320A0E1042052E2040081E4B8200B4579\r
+S214028370B0100B45F0A81B49F9FFFFEA441C0300A6\r
+S214028380541C0300001D0300081D03001C1D0300EF\r
+S214028390301D0300681B03005C1C03000DC0A0E137\r
+S2140283A0F0D82DE904B04CE2BC429FE5AC504BE25B\r
+S2140283B0C4D04DE2B0C04BE2B4E04BE20060A0E1B4\r
+S2140283C00170A0E10500A0E17310A0E30120A0E384\r
+S2140283D00030A0E300508DE808408DE5EF1700EB73\r
+S2140283E0B8C04BE200C08DE580C29FE5BCE04BE220\r
+S2140283F094004BE26C10A0E30120A0E30030A0E35F\r
+S21402840004E08DE508C08DE5E41700EBC0C04BE242\r
+S214028410C4E04BE27C004BE26410A0E30120A0E340\r
+S2140284200030A0E300508DE808408DE5DB1700EB36\r
+S2140284300040A0E338E29FE5C8C04BE264004BE28E\r
+S2140284403410A0E30420A0E10230A0E300C08DE5D2\r
+S21402845010408DE9D11700EB18E29FE5CCC04BE245\r
+S2140284604C004BE23210A0E30420A0E10230A0E36D\r
+S21402847000C08DE510408DE9C81700EBF8E19FE5D6\r
+S214028480D0C04BE234004BE23110A0E30420A0E15E\r
+S2140284900230A0E300C08DE510408DE9BF1700EB67\r
+S2140284A006C0A0E300C08DE5D0C19FE50600A0E1AE\r
+S2140284B00710A0E10530A0E10120A0E308408DE509\r
+S2140284C00CC08DE504408DE5BD1700EB040050E1BD\r
+S2140284D0F0A81B09B4301BE5040053E10500000AAE\r
+S2140284E0C4301BE5040053E10200000ABC301BE561\r
+S2140284F0040053E10200001A84019FE58E0F00EB90\r
+S214028500F0A81BE9D0301BE5000053E31E00000A6A\r
+S214028510B8301BE5013043E2000053E3B8300BE508\r
+S214028520F0A81BB9B0E01BE5C0401BE501308EE2A7\r
+S214028530012084E2B0300BE5C0200BE50010DEE53A\r
+S2140285400030D4E5030051E10500001AB8301BE5FF\r
+S214028550013043E2000053E3B8300BE5F0A81BB944\r
+S214028560EFFFFFEAB0E00BE5C0400BE50020DEE5DA\r
+S21402857000C0D4E50C019FE50E10A0E10430A0E196\r
+S21402858000C08DE56C0F00EBF0A81BE9CC301BE5B4\r
+S214028590000053E31C00000AB8301BE5023043E239\r
+S2140285A0000053E3B8300BE5F0A81BB9B0C01BE5DA\r
+S2140285B0C0E01BE5B040DCE1B050DEE102208CE218\r
+S2140285C002308EE2050054E1B0200BE5C0300BE528\r
+S2140285D00500001AB8301BE5023043E2000053E300\r
+S2140285E0B8300BE5F0A81BB9EFFFFFEA98009FE54D\r
+S2140285F00C10A0E10420A0E10E30A0E100508DE5B1\r
+S214028600B0C00BE5C0E00BE5DDFFFFEAB8301BE5C6\r
+S214028610043043E2000053E3B8300BE5F0A81BB980\r
+S214028620B0C01BE5C0E01BE500409CE500509EE59F\r
+S21402863004208CE204308EE2050054E1B0200BE503\r
+S214028640C0300BE50500001AB8301BE5043043E2E3\r
+S214028650000053E3B8300BE5F0A81BB9EFFFFFEAC2\r
+S21402866028009FE50C10A0E1E1FFFFEA441C03008E\r
+S214028670541C0300081D03001C1D0300301D0300CC\r
+S214028680681B0300441D03007C1D0300A81D030095\r
+S214028690D41D03000DC0A0E1F0D92DE904B04CE2D0\r
+S2140286A00180A0E388429FE5B0504BE2C4D04DE281\r
+S2140286B0B4C04BE2B8E04BE20060A0E10170A0E17A\r
+S2140286C00500A0E17310A0E30820A0E10030A0E3BB\r
+S2140286D000508DE808408DE5301700EBBCC04BE239\r
+S2140286E000C08DE54CC29FE5C0E04BE298004BE22D\r
+S2140286F06C10A0E30820A0E10030A0E304E08DE5C2\r
+S21402870008C08DE5251700EBC4C04BE2C8E04BE27B\r
+S21402871080004BE26410A0E30820A0E10030A0E352\r
+S21402872000508DE808408DE51C1700EB0040A0E3E2\r
+S21402873004E29FE5CCC04BE268004BE23410A0E3B3\r
+S2140287400420A0E10230A0E300C08DE510408DE9D0\r
+S214028750121700EBE4E19FE5D0C04BE250004BE27B\r
+S2140287603210A0E30420A0E10230A0E300C08DE5B1\r
+S21402877010408DE9091700EBC4E19FE5D4C04BE237\r
+S21402878038004BE23110A0E30420A0E10230A0E35F\r
+S21402879000C08DE510408DE9001700EB06C0A0E38F\r
+S2140287A000C08DE59CC19FE50600A0E10710A0E190\r
+S2140287B00530A0E10820A0E108408DE50CC08DE55B\r
+S2140287C004408DE5FE1600EB040050E1F0A91B09FB\r
+S2140287D0B8301BE5040053E10C00000AC8301BE564\r
+S2140287E0040053E10900000AC0301BE5040053E10F\r
+S2140287F00600000ACC201BE5D0E01BE5D4C01BE532\r
+S2140288000E3082E00C3083E0080053E1020000DA0A\r
+S21402881034019FE5C80E00EBF0A91BE900005EE3F9\r
+S214028820BC301B150280A013013083120130C31323\r
+S2140288300700001A000052E30100001A00005CE381\r
+S2140288400400001ABC301BE50480A0E3033083E278\r
+S2140288500330C3E3BC300BE5B4101BE5C4201BE5B4\r
+S214028860BC301BE5010052E1030081E00800009ADB\r
+S214028870000052E10600002A033068E0010068E0CA\r
+S214028880032082E0031081E0C4200BE5B4100BE560\r
+S214028890008068E200005CE30D00000A000051E17F\r
+S2140288A0F0A91B090010D1E5C4301BE50010C3E592\r
+S2140288B0B4201BE5C4301BE5081082E0083083E0D4\r
+S2140288C0000051E1C4300BE5B4100BE5F0A91B091A\r
+S2140288D0F3FFFFEA00005EE30B00000A000051E12E\r
+S2140288E0F0A91B09C4301BE5B020D1E1081081E0D5\r
+S2140288F0B020C3E1000051E1083083E0C4300BE54C\r
+S214028900B4100BE5F0A91B09F5FFFFEA000051E1E0\r
+S214028910F0A91B09C4201BE5083091E6000051E1CE\r
+S214028920083082E6B4100B05C4200B05F0A91B091B\r
+S214028930F8FFFFEA441C0300541C0300981E0300C1\r
+S214028940AC1E0300C01E0300681B03005C1E03006F\r
+S2140289500DC0A0E1F0DF2DE904B04CE2C0D04DE23C\r
+S214028960BCC04BE2B8504BE200C08DE5E8C29FE5C2\r
+S214028970C0E04BE20060A0E10170A0E10500A0E1CA\r
+S2140289806210A0E30120A0E30030A0E304E08DE53E\r
+S21402899008C08DE5811600EBC4C04BE200C08DE531\r
+S2140289A0B8C29FE5C8E04BE2A0004BE26C10A0E321\r
+S2140289B00120A0E30030A0E30040A0E304E08DE540\r
+S2140289C008C08DE5751600EB94E29FE5CCC04BE23D\r
+S2140289D088004BE27310A0E30420A0E10230A0E37B\r
+S2140289E000C08DE510408DE96C1600EB74E29FE541\r
+S2140289F0D0C04BE270004BE23410A0E30420A0E1AA\r
+S214028A000230A0E300C08DE510408DE9631600EB4E\r
+S214028A1054E29FE5D4C04BE258004BE23210A0E38A\r
+S214028A200420A0E10230A0E300C08DE510408DE9ED\r
+S214028A305A1600EB34E29FE5D8C04BE240004BE208\r
+S214028A403110A0E30420A0E10230A0E300C08DE5CF\r
+S214028A5010408DE9511600EB06C0A0E300C08DE57C\r
+S214028A600CC29FE50600A0E10710A0E10530A0E1D8\r
+S214028A700120A0E308408DE50CC08DE504408DE59D\r
+S214028A804F1600EB040050E1F0AF1B09C0301BE5A7\r
+S214028A90040053E1DCA19F15C8101B156900001ADB\r
+S214028AA0D0A19FE500309AE5040053E16700000A72\r
+S214028AB0C8101BE5BC300BE5000051E36100001A4C\r
+S214028AC0B4919FE50110A0E3002099E5C8100BE5DC\r
+S214028AD0C4200BE5D0301BE5000053E30420A013AE\r
+S214028AE00700001AD4301BE5000053E30220A0134F\r
+S214028AF00300001AD8301BE5000053E30200000A08\r
+S214028B000120A0E374319FE50020C3E5000051E395\r
+S214028B10CC301BE52020A003C4200B05000053E345\r
+S214028B203100000AC4201BE50080A0E3020058E1E1\r
+S214028B300400003ABC301BE5002089E5023083E0E1\r
+S214028B4000308AE5F0AF1BE9100052E30270A03154\r
+S214028B501070A023BC201BE5056087E2022088E097\r
+S214028B600610A0E118019FE5F30D00EBBC201BE503\r
+S214028B700050A0E3081082E08531A0E13133A0E185\r
+S214028B80015085E2FF3003E2030055E3036086E00E\r
+S214028B90F8FFFFDA0050A0E3070055E1090000AA3B\r
+S214028BA0083082E00540D3E7D8009FE50410A0E134\r
+S214028BB0015085E2E00D00EB070055E1046086E017\r
+S214028BC0BC201BB5F5FFFFBA0610E0E1FF1001E27C\r
+S214028BD0B4009FE5D80D00EBC4201BE5078088E0B3\r
+S214028BE0020058E1D7FFFF3AD1FFFFEA8C309FE53B\r
+S214028BF00030D3E5020053E30E00000A070000CA65\r
+S214028C00010053E30100000AC4201BE5C8FFFFEA87\r
+S214028C10BC001BE5C4101BE52C0E00EBF9FFFFEAB7\r
+S214028C20040053E3F7FFFF1ABC001BE5C4101BE564\r
+S214028C30530E00EBF3FFFFEABC001BE5C4101BE576\r
+S214028C40810E00EBEFFFFFEA2C909FE5A0FFFFEA04\r
+S214028C5038009FE5B80D00EBF0AF1BE9441C03009B\r
+S214028C60541C0300901F0300B41F0300C81F030018\r
+S214028C70DC1F0300681B0300545903005859030005\r
+S214028C80B8310300001F03000C1F0300141F03006B\r
+S214028C901C1F030004E02DE504E09DE42BFFFFEA21\r
+S214028CA00DC0A0E110D82DE90030A0E10140A0E1FE\r
+S214028CB0A0109FE5020053E304B04CE298009FE543\r
+S214028CC00120A0E10100000A10681BE99A0D00EAE3\r
+S214028CD088109FE5040094E5F01000EB000050E3D6\r
+S214028CE07C109FE50900001A00200FE100400FE10A\r
+S214028CF0C04084E304F029E100300FE1C04002E204\r
+S214028D00C030C3E3043083E103F029E110A81BE975\r
+S214028D10040094E5E11000EB000050E344009FE5F8\r
+S214028D200900001A00200FE100400FE1C04084E372\r
+S214028D3004F029E100300FE1C04002E2C030C3E394\r
+S214028D40043083E103F029E110A81BE9041094E53E\r
+S214028D5010681BE9780D00EA1C200300202003009F\r
+S214028D60C8210300482003004C20030004E02DE540\r
+S214028D702C309FE52CE09FE5002093E528C09FE578\r
+S214028D800C3092E50C109EE50C308CE50C1082E55A\r
+S214028D90103092E510009EE510308CE5100082E55A\r
+S214028DA004F09DE4BC310300206002005C5903001D\r
+S214028DB018009FE518309FE50C1090E5002093E51B\r
+S214028DC00C1082E5103090E5103082E50EF0A0E13E\r
+S214028DD05C590300BC3103000DC0A0E130D82DE978\r
+S214028DE06C209FE504B04CE2003092E564509FE5AB\r
+S214028DF0000053E30040A0E10400000A443090E57E\r
+S214028E00040053E3003092053C30800530A81B096D\r
+S214028E10003095E5013083E2010053E3003085E53A\r
+S214028E200900000A30309FE5004083E5FF0200EBB0\r
+S214028E30003095E5013043E2000053E3003085E55B\r
+S214028E4030A81B19D9FFFFEB30A81BE9C6FFFFEBC2\r
+S214028E50F3FFFFEAF43103007C590300E0810300CC\r
+S214028E6004E02DE504E09DE4DAFFFFEA0DC0A0E190\r
+S214028E7030D82DE924309FE524409FE504B04CE22B\r
+S214028E80030054E130A81B390350A0E10FE0A0E133\r
+S214028E9004F014E4050054E130A81B39FAFFFFEA97\r
+S214028EA018340300183403000000A0E30EF0A0E11B\r
+S214028EB0FEDEFFE70EF0A0E10DC0A0E100D82DE92E\r
+S214028EC004B04CE2430000EB00681BE94B0900EAE1\r
+S214028ED02C309FE52CC09FE52C209FE50311A0E3D4\r
+S214028EE0001083E50030A0E3000082E500308CE548\r
+S214028EF018209FE518309FE5002083E500008CE5EA\r
+S214028F000EF0A0E1088006803080068080590300BB\r
+S214028F10CC400000208006801C309FE51C209FE588\r
+S214028F200209A0E3000083E5001082E54231A0E3D7\r
+S214028F300110A0E3001083E50EF0A0E12880068071\r
+S214028F408059030014309FE514209FE5B210D3E148\r
+S214028F50003092E5033061E0003080E50EF0A0E1DB\r
+S214028F6030800680805903000DC0A0E170D82DE93C\r
+S214028F7004B04CE20050A0E108D04DE21C004BE2E7\r
+S214028F80855085E0EEFFFFEB000055E30040A0E3CE\r
+S214028F9070A81B9920604BE20600A0E1E8FFFFEBF9\r
+S214028FA020001BE51C101BE5010050E120209F3528\r
+S214028FB000306120003092351C000BE50330613032\r
+S214028FC000308330034084E0040055E170A81B990A\r
+S214028FD0F0FFFFEA805903000DC0A0E110D82DE98A\r
+S214028FE004B04CE20040A0E30400A0E1014084E2A9\r
+S214028FF0130000EB3F0054E3FAFFFFDA04009FE59C\r
+S21402900010681BE9B1FFFFEAC05D00002C209FE557\r
+S21402901002C1A0E3001092E54000A0E3000051E385\r
+S21402902000309C050030A013C32FA001223F83000E\r
+S2140290304301A0010030821500108C050EF0A0E15D\r
+S214029040C0310300C01FA0E1211F80E04111A0E152\r
+S214029050010140E08001A0E10430A0E308209FE582\r
+S2140290601330A0E1013282E70EF0A0E16800008032\r
+S214029070C01FA0E1211F80E04111A0E1010140E0F4\r
+S2140290808001A0E10430A0E308209FE51330A0E1B0\r
+S214029090013282E70EF0A0E1640000800EF0A0E14B\r
+S2140290A00EF0A0E108309FE50F0000E20000D3E7D3\r
+S2140290B00EF0A0E16420030004E02DE518209FE5F1\r
+S2140290C0000092E5000050E30030E0C3003082C5A5\r
+S2140290D004F09DC404E09DE4930500EADC3103003D\r
+S2140290E0FF0000E2613040E2302040E2050053E338\r
+S2140290F0FF1002E2573040E20600009A090051E3F0\r
+S21402910041C040E20230A0E10200009A05005CE3A2\r
+S214029110373040E20030E0830300A0E10EF0A0E129\r
+S2140291200DC0A0E130D82DE90030A0E304B04CE237\r
+S21402913014D04DE20350A0E128404BE220000BE59C\r
+S21402914018304BE517304BE5DAFFFFEB0410A0E1D1\r
+S214029150FF0000E2090000EB0030A0E1010053E34B\r
+S2140291602D00A0E330A81B09020073E3F5FFFF1AE7\r
+S214029170610500EB18504BE517504BE5F1FFFFEA8F\r
+S2140291800DC0A0E170D82DE91040D1E504B04CE244\r
+S214029190000054E30150A0E10B00001A240050E343\r
+S2140291A00200000A0420A0E10200A0E170A81BE968\r
+S2140291B00030E0E30120A0E3043081E51020C1E5A1\r
+S2140291C00C4081E5004081E5F5FFFFEA010054E32B\r
+S2140291D03800000A020054E32E00000A030054E39B\r
+S2140291E00030A0131030C1150020E013EDFFFF1A67\r
+S2140291F0FF0000E2B9FFFFEB043095E51160D5E50C\r
+S214029200002083E1000056E3042085E50120E013F8\r
+S214029210E4FFFF1A0030D5E5020053E10400000A1D\r
+S2140292202D00A0E3340500EB0020E0E31060C5E566\r
+S214029230DCFFFFEA2B00A0E32F0500EB082095E5F4\r
+S2140292400230D2E53A0053E30100000A0120A0E30F\r
+S214029250D4FFFFEA0000D2E50C6095E5260500EB98\r
+S214029260083095E50100D3E5230500EB060054E13E\r
+S2140292700400A0E1F4FFFF8A083095E50020D3E75A\r
+S214029280003083E0010080E2060050E1032043E55F\r
+S214029290F8FFFF9AECFFFFEAFF0000E28FFFFFEB0A\r
+S2140292A00330A0E30002A0E10020A0E31030C5E5F1\r
+S2140292B0040085E5BBFFFFEA0CC091E5020B5CE308\r
+S2140292C00030A0031140C1051030C1050800000A95\r
+S2140292D0230050E30800000A003091E5081091E5EB\r
+S2140292E0003083E001208CE2003085E50C00C1E707\r
+S2140292F00C2085E50020A0E3AAFFFFEA083091E5EE\r
+S2140293000020A0E30210A0E30C20C3E71010C5E57E\r
+S214029310F7FFFFEA0DC0A0E1F0D92DE974809FE5C2\r
+S21402932004B04CE20070A0E10060A0E32400A0E3D9\r
+S214029330F10400EB0640D7E70650A0E1060054E130\r
+S2140293400B00001A2300A0E3EB0400EB2602D8E78A\r
+S214029350E90400EB0F3006E20300D8E7E60400EB70\r
+S21402936054FFFFEB7F0000E22B0050E3F0A91B093D\r
+S214029370ECFFFFEA0400A0E1015085E2DE0400EB08\r
+S214029380043086E00540D7E7FF6003E2000054E3BE\r
+S214029390F7FFFF1AEAFFFFEA642003000DC0A0E110\r
+S2140293A0F0D92DE948119FE504B04CE204D04DE215\r
+S2140293B00020A0E3003091E5000053E334319FE53E\r
+S2140293C0002083E5F0A91BD90180A0E128319FE5A2\r
+S2140293D0002093E5000052E320319F050140A003E0\r
+S2140293E0002093050010D20524104B051700000A32\r
+S2140293F0003091E5030053E30400009AFC309FE539\r
+S214029400002093E5030012E30440A0030900000ACB\r
+S214029410DC309FE5002093E5010052E30400009A49\r
+S214029420D8309FE5002093E5010012E30240A00336\r
+S2140294300000000A0140A0E3C0309FE524704BE222\r
+S214029440001093E50700A0E10420A0E1130600EB5C\r
+S214029450A0209FE5001092E5000051E3F0A91B1939\r
+S214029460040051E101E0A0E1160000AA90009FE589\r
+S21402947090609FE50250A0E124704BE20730DEE7E1\r
+S214029480001090E50FC003E22332A0E10320D6E7E6\r
+S21402949001E08EE20120C1E4003095E5001080E58F\r
+S2140294A0000053E3F0A91B190C30D6E70130C1E4E3\r
+S2140294B0002095E5001080E5000052E3F0A91B1994\r
+S2140294C004005EE1ECFFFFBA30109FE5002098E54D\r
+S2140294D0003091E5022064E0043083E0000052E3AD\r
+S2140294E0003081E5002088E50810A0E1F0A91BD92C\r
+S2140294F0B5FFFFEA84590300E031030090590300E8\r
+S214029500885903008C590300642003000DC0A0E1B3\r
+S21402951030D82DE904B04CE260C09FE50050A0E3CD\r
+S21402952000108CE558109FE5050053E1000081E528\r
+S21402953050009FE550409FE5002080E54C209FE5C7\r
+S214029540003082E50B00000A005084E592FFFFEB34\r
+S214029550003094E50500A0E1050053E130A81B1990\r
+S21402956018109FE50030A0E3002091E50030C2E528\r
+S214029570000091E530A81BE987FFFFEBF7FFFFEA43\r
+S2140295808C5903008859030084590300E031030014\r
+S2140295909059030054309FE50DC0A0E170D82DE924\r
+S2140295A0000083E548009FE548309FE548509FE568\r
+S2140295B048609FE50040A0E3002080E50120A0E38C\r
+S2140295C0002083E5004085E504B04CE2001086E505\r
+S2140295D071FFFFEB005095E50400A0E1040055E1A1\r
+S2140295E0003096050050C3050000960570A81BE9DA\r
+S2140295F0885903008459030090590300E0310300A0\r
+S2140296008C5903000DC0A0E1F0DD2DE984019FE531\r
+S21402961004B04CE204D04DE20060A0E3002090E5E6\r
+S21402962074319FE5060052E1006083E5F0AD1BD978\r
+S21402963068319FE5002093E50010D2E5060051E16F\r
+S214029640F0AD1B0900A0A0E154319FE5002093E590\r
+S214029650000052E31000000A003090E5030053E3D6\r
+S2140296600400009A3C319FE5002093E5030012E3D4\r
+S2140296700470A0030900000A18319FE5002093E554\r
+S214029680010052E30400009A18319FE5002093E59A\r
+S214029690010012E30270A0030000000A0170A0E3BA\r
+S2140296A00050A0E3070055E11A0000AAEC409FE52F\r
+S2140296B0E4809FE5003094E50100D3E4003084E5C1\r
+S2140296C0FF0000E285FEFFEB003098E50002A0E115\r
+S2140296D0000053E3FF6000E2F0AD1B19003094E592\r
+S2140296E00100D3E4003084E5FF0000E27BFEFFEBDE\r
+S2140296F0003098E5000086E1000053E3FF6000E2D8\r
+S214029700F0AD1B1928304BE20360C5E7015085E235\r
+S214029710070055E1E6FFFFBA84309FE5002093E597\r
+S214029720000052E31500001A78409FE5003094E5E9\r
+S2140297300060C3E560309FE5002093E5000052E339\r
+S214029740F0AD1B1900209AE5003094E5022067E090\r
+S214029750073083E0000052E3003084E500208AE50B\r
+S2140297600A00A0E1F0AD1BD930309FE5002093E55A\r
+S2140297700010D2E5000051E3F0AD1B09B1FFFFEA8D\r
+S21402978020409FE528004BE2001094E50720A0E168\r
+S214029790570500EBE6FFFFEA84590300E0310300B9\r
+S2140297A088590300905903008C5903000DC0A0E1AC\r
+S2140297B030D82DE904B04CE254C09FE50050A0E337\r
+S2140297C000008CE54C009FE5050053E1001080E5A3\r
+S2140297D044109FE544409FE5002081E540209FE538\r
+S2140297E0003082E50800000A005084E584FFFFEBA3\r
+S2140297F0003094E50500A0E1050053E130A81B19EE\r
+S21402980010309FE5000093E530A81BE97CFFFFEBD4\r
+S214029810FAFFFFEA885903008C59030084590300B3\r
+S214029820E0310300905903004C309FE50DC0A0E1E3\r
+S21402983070D82DE9000083E540009FE540309FE5A3\r
+S214029840002080E53C609FE53C509FE50120A0E3B8\r
+S2140298500040A0E3002083E504B04CE2001086E559\r
+S214029860004085E566FFFFEB003095E50400A0E1C9\r
+S214029870040053E10000960570A81BE9885903000E\r
+S21402988084590300905903008C590300E031030009\r
+S2140298900DC0A0E100D82DE904B04CE2520400EB62\r
+S2140298A008309FE50120A0E3002083E500A81BE91D\r
+S2140298B0C43103000DC0A0E170D82DE90060A0E31A\r
+S2140298C0002090E5006081E50030D2E504B04CE26D\r
+S2140298D0060053E10050A0E10140A0E10100001A99\r
+S2140298E00600A0E170A81BE90000D2E5FBFDFFEB35\r
+S2140298F0000050E3F9FFFFBA001095E5003094E54A\r
+S214029900012081E2033280E1003084E5002085E513\r
+S2140299100130D1E5016086E2000053E3F1FFFF1A51\r
+S214029920EEFFFFEA0DC0A0E170D82DE90060A0E3CB\r
+S214029930002090E5006081E50030D2E504B04CE2FC\r
+S214029940060053E10050A0E10140A0E10100001A28\r
+S2140299500600A0E170A81BE90000D2E5DFFDFFEBE0\r
+S214029960000050E3F9FFFFBA001095E5003094E5D9\r
+S214029970012081E2033280E1003084E5002085E5A3\r
+S2140299800130D1E5016086E2000053E3F1FFFF1AE1\r
+S214029990EEFFFFEA000051E33030A00370402DE9ED\r
+S2140299A00130C0040140A0E10050A0E30220A00361\r
+S2140299B00030C0051800000A073082E2C32FA0E17B\r
+S2140299C0A23E83E0C3C1B0E11200000A8C31A0E1DE\r
+S2140299D04C609FE508E043E2342EB0E10030A0037D\r
+S2140299E00130A01301005CE301308303000053E35F\r
+S2140299F0FF2002E22232D6170F1002E20120D6170B\r
+S214029A000130C014025085120120C01401C05CE26D\r
+S214029A1008E04EE2EFFFFF1A0520A0E10200A0E1F7\r
+S214029A207080BDE8642003000EF0A0E10EF0A0E115\r
+S214029A300DC0A0E130D82DE9FC209FE50050A0E340\r
+S214029A40003092E504B04CE2050053E13600001AFD\r
+S214029A506F1500EB000050E32900001ADC209FE59A\r
+S214029A60003092E5000053E30030A0130250A0132A\r
+S214029A7000308215000055E31D00000AED1700EBCA\r
+S214029A80000050E31800001AE91700EBE6FFFFEBB0\r
+S214029A90D31700EB0300A0E33E0400EB0300A0E3B1\r
+S214029AA03A0400EB000055E30600000A90409FE5EA\r
+S214029AB0003094E50500A0E10FE0A0E103F0A0E18C\r
+S214029AC0000050E3F9FFFF1AD81700EB74209FE559\r
+S214029AD0003092E5000053E330A81B09003092E5FF\r
+S214029AE00FE0A0E103F0A0E130A81BE9DC1700EBD1\r
+S214029AF0E4FFFFEA411500EB311500EB0050A0E150\r
+S214029B00DDFFFFEA531800EB000050E30050A0E12F\r
+S214029B10D1FFFFCAECFFFFAA2C309FE5002093E599\r
+S214029B200FE0A0E102F0A0E1E7FFFFEA003092E5D5\r
+S214029B300FE0A0E103F0A0E1C4FFFFEAD831030082\r
+S214029B40C0820300C8310300D4310300CC310300C5\r
+S214029B500DC0A0E1F0DD2DE904B04CE22CD04DE2C0\r
+S214029B600020A0E10030D0E50170A0E1700053E3D0\r
+S214029B700000A0E31AA0A0E34A00000A0A0050E18F\r
+S214029B800050A0E1F0AD1BA9106045E2070056E3C5\r
+S214029B900180A0E33D00009A40319FE5003093E546\r
+S214029BA0000053E33400000A50404BE20500A0E1F7\r
+S214029BB00410A0E10FE0A0E103F0A0E10080A0E124\r
+S214029BC0070056E30400A0E10F00008A0010A0E39D\r
+S214029BD024204BE20730A0E3013053E21C1042E59A\r
+S214029BE0012082E2FBFFFF5A44004BE20410A0E190\r
+S214029BF000C0A0E10320A0E30130D1E4012042E24C\r
+S214029C00010072E30130CCE4FAFFFF1A000058E3C9\r
+S214029C101100001A070056E31730A0930730A083FE\r
+S214029C20010073E30720A0E17810A0E30300000A16\r
+S214029C30013043E2010073E30110C2E4FBFFFF1AA6\r
+S214029C40070056E30870878218708792015085E2F3\r
+S214029C500A0055E1F0AD1BA9CAFFFFEA070056E36A\r
+S214029C600710A0E10C20A0930420A0830030A0E3FC\r
+S214029C7025FEFFEB0070A0E1F3FFFFEA0500A0E17E\r
+S214029C80111500EB50404BE250000BE5CBFFFFEA0C\r
+S214029C9044404BE20500A0E10410A0E1291500EBC8\r
+S214029CA00400A0E1D8FFFFEA013082E248004BE25E\r
+S214029CB04C104BE248300BE5FDFEFFEB000050E394\r
+S214029CC04C001B1501A08012ABFFFF1A0700A0E193\r
+S214029CD00C109FE50820A0E36D0A00EBF0AD1BE92F\r
+S214029CE000790300782003000DC0A0E1F0DD2DE925\r
+S214029CF004B04CE22CD04DE201A0A0E10030D0E549\r
+S214029D00010080E2500053E348000BE51A60A0E32E\r
+S214029D100000A0E32B00000A060050E10040A0E18C\r
+S214029D20180000AA0070A0E344804BE2105044E200\r
+S214029D30070055E30810A0E10730A0E150700BE5DC\r
+S214029D401500008A070055E30C20A0930420A08388\r
+S214029D5048001BE594FEFFEB0400A0E10810A0E11A\r
+S214029D600F1500EB070055E348301B8548301B955E\r
+S214029D70014084E20830838218308392060054E160\r
+S214029D8048300BE5E8FFFFBA78109FE50A00A0E12D\r
+S214029D900320A0E33E0A00EBF0AD1BE9070055E303\r
+S214029DA050104BE20C20A0930420A08348001BE531\r
+S214029DB00030A0E37CFEFFEB0400A0E150101BE5A0\r
+S214029DC0D11400EBE6FFFFEA48004BE24C104BE2F0\r
+S214029DD0B7FEFFEB000050E30600000A48301BE522\r
+S214029DE00120D3E43D0052E34C001B0548300BE54E\r
+S214029DF001608002C7FFFF0A0C109FE50A00A0E17F\r
+S214029E000420A0E3E2FFFFEA802003008420030090\r
+S214029E100DC0A0E170D82DE964359FE50050A0E39F\r
+S214029E2004B04CE2B4D04DE20040A0E10050C3E5DD\r
+S214029E300020D0E53F3042E2340053E303F19F971F\r
+S214029E40F20000EA189F020010A20200649F0200BD\r
+S214029E50789F020048A20200E49F020010A20200BD\r
+S214029E6010A2020050A10200549F020010A202009B\r
+S214029E7010A2020010A2020010A2020008A0020015\r
+S214029E8010A2020010A2020050A102005CA1020071\r
+S214029E9010A2020048A20200549F020010A2020072\r
+S214029EA010A2020010A2020068A1020010A2020084\r
+S214029EB010A2020010A2020010A2020010A20200CB\r
+S214029EC010A2020010A2020010A2020010A20200BB\r
+S214029ED070A1020048A2020010A2020010A2020014\r
+S214029EE010A2020020A2020010A2020010A202008B\r
+S214029EF010A20200EC9F020010A20200A8A102001B\r
+S214029F0010A2020010A2020020A202002CA202004E\r
+S214029F1038A2020048A20200381400EB281400EB14\r
+S214029F2060249FE54032A0E10F3003E20F0000E21A\r
+S214029F304C149FE500C0D2E70300D2E70030A0E34E\r
+S214029F405320A0E30330C1E50020C1E50100C1E5CE\r
+S214029F5002C0C1E528049FE5EDFCFFEB0000A0E38C\r
+S214029F6070A81BE918049FE51C149FE50420A0E3D3\r
+S214029F70C70900EBF6FFFFEA013080E2C4104BE2AD\r
+S214029F80C0004BE2C0300BE549FEFFEB000050E399\r
+S214029F90F3FFFF0AC0201BE50130D2E42C0053E396\r
+S214029FA0C0200BE5EEFFFF1A0130D2E4430053E374\r
+S214029FB0C0200BE50600000A0010A0E3C4001BE563\r
+S214029FC0630300EBB8039FE5C0139FE50320A0E3FD\r
+S214029FD0E6FFFFEA0010A0E3C4001BE55E0300EB09\r
+S214029FE0F7FFFFEA98039FE5C9FCFFEBDA0100EBF7\r
+S214029FF09C339FE5002093E50FE0A0E102F0A0E18C\r
+S21402A0000000E0E370A81BE9A8604BE2013084E29E\r
+S21402A010AC104BE20600A0E1A8300BE540FEFFEBD9\r
+S21402A020000050E30400000AA8301BE50120D3E438\r
+S21402A0302C0052E3A8300BE50200000A40039FE51D\r
+S21402A04050139FE5C8FFFFEA0600A0E1B0104BE2FE\r
+S21402A05017FEFFEB000050E3F7FFFF0AA8001BE520\r
+S21402A0600130D0E43A0053E3A8000BE5F2FFFF1AF2\r
+S21402A070B0301BE5020B53E30320A0E1B8FFFF2A32\r
+S21402A080000055E32B00000A000053E32400000AF8\r
+S21402A09098504BE20040A0E3020054E11000002A70\r
+S21402A0A018104BE2A8201BE5014084E20130D2E4FE\r
+S21402A0B0803041E57D0053E3A8200BE50130D20451\r
+S21402A0C02030830380304105A8200B057F0054E32F\r
+S21402A0D0011081E20200008AB0301BE5030054E161\r
+S21402A0E0EFFFFF3A0500A0E1AC101BE50420A0E15B\r
+S21402A0F0FF0200EB040050E10800001AB0201BE546\r
+S21402A100AC301BE5022064E0043083E0000052E33A\r
+S21402A110AC300BE5B0200BE5DDFFFF1AA8FFFFEA27\r
+S21402A120B0201BE5000052E3A5FFFF0A50029FE5A0\r
+S21402A13064129FE58CFFFFEAAC101BE50320A0E14A\r
+S21402A140B8FDFFEB000050E39DFFFF1AF6FFFFEAA3\r
+S21402A1502C129FE5E3FEFFEB7DFFFFEA010080E2A3\r
+S21402A1605A0100EB7AFFFFEA0150A0E3A5FFFFEADF\r
+S21402A170013080E2CC104BE2C8004BE2C8300BE55F\r
+S21402A180CBFDFFEB000050E3F4019F050C129F0588\r
+S21402A19075FFFF0AF4019FE55DFCFFEBCC001BE5B3\r
+S21402A1A0790100EB6AFFFFEA9C504BE2013080E245\r
+S21402A1B0A0104BE20500A0E19C300BE5D8FDFFEBBA\r
+S21402A1C0000050E366FFFF0A9C301BE50120D3E443\r
+S21402A1D02C0052E39C300BE561FFFF1A0500A0E15C\r
+S21402A1E0A4104BE2B2FDFFEB000050E35CFFFF0A57\r
+S21402A1F08C419FE5A0001BE5A4201BE50410A0E10E\r
+S21402A200E3FCFFEB000050E351FFFF1AC6FFFFEA34\r
+S21402A2106C119FE54B2FA0E3CB0200EB4CFFFFEA4D\r
+S21402A2205C119FE549FEFFEB49FFFFEA010080E271\r
+S21402A230D90000EB46FFFFEA64219FE550319FE517\r
+S21402A240002083E542FFFFEA013080E20050A0E3EF\r
+S21402A250530052E343005213B4300BE5B8500BE5FB\r
+S21402A2603D00000AB4504BE20500A0E1BC104BE2F0\r
+S21402A270ABFDFFEB000050E33400001A0300A0E33E\r
+S21402A280440200EB0300A0E3400200EBB8501BE5DB\r
+S21402A290000055E30500000A08219FE5003092E51C\r
+S21402A2A0000053E32000001A000055E31900001ACC\r
+S21402A2B0621600EB000050E36330A0130030C415B2\r
+S21402A2C0E4309F150120A013002083150030D4E54A\r
+S21402A2D0530053E3730053130700000A0100A0E380\r
+S21402A2E0D0FDFFEB0300A0E32A0200EB0300A0E38D\r
+S21402A2F0260200EB180100EB40FFFFEA0500A0E192\r
+S21402A300C8FDFFEBA4209FE5A4309FE5002083E56F\r
+S21402A310831500EBF2FFFFEA0950A0E30500A0E177\r
+S21402A320B8500BE54F0000EB0BFFFFEA0500A0E17B\r
+S21402A330003092E50FE0A0E103F0A0E1000050E358\r
+S21402A340B8501B150050A001B8000B05D5FFFFEA58\r
+S21402A350BC001BE5491300EBC7FFFFEAB4504BE213\r
+S21402A360B8104BE20500A0E151FDFFEBB4201BE55F\r
+S21402A3700030D2E53B0053E301308202B4300B05D5\r
+S21402A380B8FFFFEA00710300642003008820030080\r
+S21402A39080200300CC3103008C20030090200300B1\r
+S21402A3A09420030068AA0200D03103001C32030086\r
+S21402A3B020810300E83103000DC0A0E110D82DE98A\r
+S21402A3C014409FE504B04CE20410A0E1B00100EB9B\r
+S21402A3D00400A0E110681BE9CDFBFFEA0071030050\r
+S21402A3E00DC0A0E110D82DE93C309FE504B04CE248\r
+S21402A3F0002093E5000052E3090000BA2C409FE5D6\r
+S21402A4000400A0E145FBFFEB0400A0E17FFEFFEBAA\r
+S21402A410000050E3F9FFFF0A0000E0E1A00FA0E110\r
+S21402A42010A81BE9E3FFFFEBF3FFFFEADC310300B2\r
+S21402A430087903000EF0A0E10DC0A0E100D82DE9D6\r
+S21402A44004B04CE211FDFFEB7C0100EB2B00A0E315\r
+S21402A45000681BE9A80000EA04309FE5000083E5D7\r
+S21402A4600EF0A0E1DC31030010402DE938109FE524\r
+S21402A4704032A0E134209FE50F3003E20F0000E2F5\r
+S21402A4800040D1E703C0D1E75830A0E30030C2E570\r
+S21402A4900200A0E1583043E201C0C2E50240C2E534\r
+S21402A4A00330C2E51040BDE899FBFFEA64200300D2\r
+S21402A4B0007103000DC0A0E1F0D92DE9C8809FE528\r
+S21402A4C004B04CE204D04DE20140A0E100E098E581\r
+S21402A4D00260A0E100005EE30050A0E11000001A56\r
+S21402A4E00130A0E3A4C09FE5A4709FE5003088E594\r
+S21402A4F00E00A0E1003CA0E10810A0E3000053E338\r
+S21402A5008320A0E10C2022B0011051E20230A0E12B\r
+S21402A510F9FFFF1A002187E7010080E2FF0050E3FF\r
+S21402A520F3FFFF9A014044E268309FE50020A0E373\r
+S21402A530010074E3002083E51100000A50809FE5C5\r
+S21402A54021704BE20510A0E10120A0E30700A0E184\r
+S21402A550D20100EB3C309FE5014044E2002093E547\r
+S21402A560015085E2000052E30500001A21305BE547\r
+S21402A570010074E3263C23E0032198E7066422E008\r
+S21402A580EFFFFF1A0600A0E1F0A91BE9E431030081\r
+S21402A590B71DC10494590300E03103000DC0A0E1C9\r
+S21402A5A070D82DE918419FE50030A0E304B04CE2D4\r
+S21402A5B00CD04DE20020A0E10030C4E50030D0E52A\r
+S21402A5C01C000BE5430053E30D00000A0030D2E501\r
+S21402A5D04C0053E370A81B09060000CA430053E36D\r
+S21402A5E070A81B090200A0E1D4109FE54B2FA0E340\r
+S21402A5F0D10100EB70A81BE9500053E3F8FFFF1AE5\r
+S21402A60070A81BE90130D0E5520053E3EEFFFF1AB3\r
+S21402A6100250D0E5430055E3EBFFFF1A0330D0E5C6\r
+S21402A6203A0053E3E8FFFF1A043080E218604BE278\r
+S21402A630043026E520104BE20600A0E1B8FCFFEB52\r
+S21402A640000050E370A81B091C301BE50120D3E470\r
+S21402A6502C0052E31C300BE570A81B190600A0E183\r
+S21402A66024104BE292FCFFEB000050E370A81B099B\r
+S21402A67024101BE520001BE50020E0E38CFFFFEB27\r
+S21402A68040309FE50010A0E1006093E5000056E32D\r
+S21402A6900400000A0400A0E12C109FE50420A0E3B9\r
+S21402A6A0FB0700EB70A81BE9010084E22020A0E370\r
+S21402A6B0B7FCFFEB040080E00050C4E50160C0E593\r
+S21402A6C070A81BE900710300E03103008820030034\r
+S21402A6D00DC0A0E100D82DE904B04CE200C0D0E5E0\r
+S21402A6E04B2FA0E370005CE308109FE500A81B094F\r
+S21402A6F0930100EB00A81BE9007103000DC0A0E166\r
+S21402A70000D82DE91C309FE5FF1000E2182093E5E3\r
+S21402A71004B04CE2000092E50C3092E50FE0A0E1B6\r
+S21402A72003F0A0E100A81BE9500000000DC0A0E164\r
+S21402A73000D82DE91C309FE504B04CE2182093E5C2\r
+S21402A740000092E5103092E50FE0A0E103F0A0E1F0\r
+S21402A750FF0000E200A81BE9500000000DC0A0E1C7\r
+S21402A76000D82DE91C309FE504B04CE2182093E592\r
+S21402A7700810A0E3000092E5143092E50FE0A0E195\r
+S21402A78003F0A0E100A81BE9500000000DC0A0E104\r
+S21402A79000D82DE920309FE50020A0E1181093E5AF\r
+S21402A7A004B04CE2000091E5143091E50010A0E3FD\r
+S21402A7B00FE0A0E103F0A0E100A81BE950000000B2\r
+S21402A7C00DC0A0E1000050E300D82DE904B04CE231\r
+S21402A7D068E09FE50E00000A00309EE50510A0E343\r
+S21402A7E0013043E2000053E300308EE500A81BC9A7\r
+S21402A7F04C309FE50020A0E318C093E500208EE5CC\r
+S21402A80000009CE514309CE50FE0A0E103F0A0E117\r
+S21402A81000A81BE900309EE50410A0E3013083E2A5\r
+S21402A820010053E300308EE500A81B1910309FE5A7\r
+S21402A830182093E5000092E5143092E5F1FFFFEA56\r
+S21402A840EC310300500000000DC0A0E100D82DE955\r
+S21402A85010309FE504B04CE2542093E50FE0A0E1EF\r
+S21402A86002F0A0E100A81BE95000000004E02DE57C\r
+S21402A87004009FE504E09DE4001200EA48A80200F6\r
+S21402A8800DC0A0E110D82DE90000A0E304B04CE210\r
+S21402A890CAFFFFEBBC309FE5BCE09FE5002093E5D6\r
+S21402A8A00000A0E3003192E700318EE7010080E26B\r
+S21402A8B00A0050E3FAFFFFDA98309FE59CC09FE556\r
+S21402A8C0001093E50040A0E32C2091E51700A0E3DA\r
+S21402A8D02C208EE5303091E530308EE5342091E53F\r
+S21402A8E034208EE5383091E538308EE53C2091E50F\r
+S21402A8F03C208EE5403091E5A4308EE5010050E222\r
+S21402A90004408CE4FCFFFF5A54C09FE548209FE5B4\r
+S21402A91000309CE50010A0E3000053E344309FE5BE\r
+S21402A920A0108EE5002083E50500001A0F00A0E3C4\r
+S21402A930E51100EB7A1400EB2C309FE5000083E56E\r
+S21402A94010A81BE900108CE50F00A0E3DE1100EB57\r
+S21402A950731400EBF4FFFFEAE0810300208103009A\r
+S21402A960608103001C320300E8310300C08203004A\r
+S21402A97004E02DE560309FE560C09FE5001093E59A\r
+S21402A9800020A0E302319CE7023181E7012082E247\r
+S21402A9900A0052E3FAFFFFDA3C309FE52C209CE5E2\r
+S21402A9A0001093E50100A0E32C2081E530309CE501\r
+S21402A9B0303081E534209CE5342081E538309CE552\r
+S21402A9C0383081E53C209CE53C2081E5A4309CE5BE\r
+S21402A9D0403081E504E09DE478FFFFEAE081030071\r
+S21402A9E0208103000000A0E30EF0A0E12C209FE5EA\r
+S21402A9F02C309FE52C109FE5002083E528309FE54C\r
+S21402AA0028209FE5001083E524309FE524109FE56B\r
+S21402AA10002083E520309FE5001083E50EF0A0E1DC\r
+S21402AA20E4A90200D03103006CA80200CC31030076\r
+S21402AA3080A80200D831030070A90200D4310300B6\r
+S21402AA4004E02DE518209FE5003092E5000053E370\r
+S21402AA5004F09D140130A0E3003082E504E09DE49A\r
+S21402AA60A81500EAF03103000DC0A0E100D82DE9D8\r
+S21402AA7018309FE504B04CE2403093E5000053E303\r
+S21402AA8000A81B090FE0A0E103F0A0E100A81BE963\r
+S21402AA90500000000DC0A0E1F0D92DE95430A0E32B\r
+S21402AAA004B04CE20040A0E30180A0E108D04DE2F1\r
+S21402AAB00060A0E14002A0E128400BE50130C8E4B6\r
+S21402AAC00150A0E176F9FFEB0100C5E50600A0E122\r
+S21402AAD073F9FFEB018088E20100C8E40400A0E1FC\r
+S21402AAE06FF9FFEB0100C8E40F00A0E36CF9FFEB7F\r
+S21402AAF03A70A0E30100C8E40170C8E40F00A0E3C6\r
+S21402AB00711100EB20504BE2040025E50810A0E18D\r
+S21402AB100420A0E30430A0E10500A0E17AFAFFEBEE\r
+S21402AB200420A0E10010A0E10430A0E128004BE2DE\r
+S21402AB3075FAFFEB3B60A0E30080A0E10160C8E489\r
+S21402AB400400A0E156F9FFEB0100C8E40D00A0E303\r
+S21402AB5053F9FFEB0100C8E40170C8E40D00A0E35E\r
+S21402AB60591100EB0810A0E100C0A0E10420A0E308\r
+S21402AB700500A0E10430A0E124C00BE562FAFFEB79\r
+S21402AB800080A0E10160C8E40040C8E5F0A91BE926\r
+S21402AB900000A0E30EF0A0E10000A0E30EF0A0E1AA\r
+S21402ABA010402DE9E4E09FE501C0A0E100309EE5FB\r
+S21402ABB0000053E33300000AD4309FE5D4409FE5FB\r
+S21402ABC0D4209FE50110A0E3001083E5002084E571\r
+S21402ABD000309EE5000053E31000000A0E10A0E1CC\r
+S21402ABE000309EE5030053E31200009A03001CE3C4\r
+S21402ABF01000001A030010E30E00001A042090E46E\r
+S21402AC0004208CE400309EE5043043E200308EE5FA\r
+S21402AC1078E09FE500309EE5000053E3EFFFFF1A61\r
+S21402AC206C309FE50020A0E3002083E50030A0E31F\r
+S21402AC30003084E51080BDE850209FE5003092E5A4\r
+S21402AC40010053E30900009A01001CE30700001A02\r
+S21402AC50010010E30500001A003092E5B2E0D0E0F1\r
+S21402AC60023043E2B2E0CCE0003082E5E7FFFFEAE2\r
+S21402AC700120D0E40120CCE4003091E5013043E22B\r
+S21402AC80003081E5E1FFFFEA08409FE5E6FFFFEAC4\r
+S21402AC90945D0300E0310300F43103002CAC0200A3\r
+S21402ACA00DC0A0E10130A0E1070171E330D82DE923\r
+S21402ACB00240A0E104B04CE2022081E02C509FE565\r
+S21402ACC00010A0E10300A0E10200008A1D0272E368\r
+S21402ACD00030A0E30300008A004085E5AFFFFFEBEB\r
+S21402ACE0003095E5043063E00300A0E130A81BE9DC\r
+S21402ACF0945D03000DC0A0E1070171E330D82DE991\r
+S21402AD00023081E004B04CE228509FE50240A0E108\r
+S21402AD100200008A1D0273E30030A0E30300008AEB\r
+S21402AD20004085E59DFFFFEB003095E5043063E0CB\r
+S21402AD300300A0E130A81BE9945D03000000A0E335\r
+S21402AD400EF0A0E10000A0E30EF0A0E10000A0E3F8\r
+S21402AD500EF0A0E10100A0E30EF0A0E10100A0E3E6\r
+S21402AD600EF0A0E104E02DE504E09DE47DF8FFEAA4\r
+S21402AD700732A0E303F0A0E10000A0E30EF0A0E19A\r
+S21402AD80020070E30DC0A0E1D8309F05D8209F05D1\r
+S21402AD9070D82DE904B04CE200C0A0E30040A0E168\r
+S21402ADA00160A0E30C10A0E118C083050000820534\r
+S21402ADB00500000A210000CA030070E30C40A0014F\r
+S21402ADC00000000A014084E20110A0E3000051E303\r
+S21402ADD01800000A8C509FE5183095E5000053E3F2\r
+S21402ADE00500000A000093E50410A0E3143093E582\r
+S21402ADF00FE0A0E103F0A0E100C0A0E16C309FE507\r
+S21402AE0000005CE3843283E0183085E558309FE525\r
+S21402AE100510A013004083E5183095E50410A00342\r
+S21402AE200000931500009305143093151430930513\r
+S21402AE300FE0A0E103F0A0E10600A0E170A81BE984\r
+S21402AE40010070E3DEFFFF1A1C309FE5000093E569\r
+S21402AE50000050E3016040C2DBFFFFCA0260E0036D\r
+S21402AE600060A011D8FFFFEA50000000F83103008E\r
+S21402AE70985D0300020070E37C309F057C209F05EE\r
+S21402AE800010A0E301C0A0E31410830500008205B1\r
+S21402AE900500000A0E0000CA030070E30100A001CC\r
+S21402AEA00000000A010080E20110A0E3000051E366\r
+S21402AEB00500000A48309FE53C209FE53C109FE5D0\r
+S21402AEC0803283E0143082E5000081E50C00A0E1C8\r
+S21402AED00EF0A0E1010070E3F1FFFF1A1C309FE5BF\r
+S21402AEE0003093E5000053E301C043C2EEFFFFCA01\r
+S21402AEF002C0E00303C0A011EBFFFFEA500000000F\r
+S21402AF00FC310300985D03000EF0A0E10EF0A0E114\r
+S21402AF100DC0A0E100D82DE91C309FE504B04CE23C\r
+S21402AF20182093E5000092E5103092E50FE0A0E1CC\r
+S21402AF3003F0A0E1FF0000E200A81BE950000000B9\r
+S21402AF400DC0A0E1F0DF2DE9AC319FE504B04CE284\r
+S21402AF5004D04DE2A4219FE5001093E5186092E527\r
+S21402AF60000051E3F0AF1B0900900FE100400FE133\r
+S21402AF70C04084E304F029E184019FE5C71200EB98\r
+S21402AF80000096E52410A0E30C3096E50FE0A0E161\r
+S21402AF9003F0A0E1000096E54F10A0E30C3096E522\r
+S21402AFA00FE0A0E103F0A0E14C319FE50070A0E3C2\r
+S21402AFB0002093E54F80A0E3020057E1190000AAA3\r
+S21402AFC040A19FE540319FE5000096E50720D3E7C4\r
+S21402AFD0017087E22232A0E10340DAE70F2002E2A4\r
+S21402AFE00250DAE70410A0E10C3096E50FE0A0E18B\r
+S21402AFF003F0A0E1000096E50510A0E10C3096E50E\r
+S21402B0000FE0A0E103F0A0E1EC309FE5044088E009\r
+S21402B010002093E5FF8004E2055088E0020057E135\r
+S21402B020FF8005E2E6FFFFBA000096E52310A0E3E4\r
+S21402B0300C3096E50FE0A0E103F0A0E1C4309FE5F6\r
+S21402B040000096E52812D3E70C3096E50FE0A0E163\r
+S21402B05003F0A0E1AC309FE50F2008E20210D3E730\r
+S21402B060000096E50C3096E50FE0A0E103F0A0E1C3\r
+S21402B070000096E5103096E50FE0A0E103F0A0E1AF\r
+S21402B080FF0000E22B0050E329004BE50B00000A0C\r
+S21402B09029004BE20110A0E31C0100EB000050E384\r
+S21402B0A058309F150120A013442083150300001A70\r
+S21402B0B029305BE52D0053E3B0FFFF0AEBFFFFEA02\r
+S21402B0C034309FE50020A0E3002083E530009FE5B2\r
+S21402B0D0931200EB00300FE1C04009E2C030C3E338\r
+S21402B0E0043083E103F029E10190A0E3000059E374\r
+S21402B0F0019049E2F0AF1B09FBFFFFEA00320300B2\r
+S21402B10050000000ECB0020098200300D85D030057\r
+S21402B110FF1001E20D0051E304E02DE52CC09FE58F\r
+S21402B12004F09D0400209CE524309FE50A0051E3CC\r
+S21402B1300310C2E7012082E200208CE50100000A2B\r
+S21402B140640052E304F09D1404E09DE47BFFFFEAF2\r
+S21402B15000320300D85D03000DC0A0E1000052E3F8\r
+S21402B16070D82DE904B04CE20060A0E10150A0E1E5\r
+S21402B170014042E270A81B090110D5E40600A0E1D6\r
+S21402B180FF1001E2E1FFFFEB000054E3014044E25E\r
+S21402B19070A81B09F7FFFFEA0DC0A0E1000052E30A\r
+S21402B1A070D82DE904B04CE20060A0E10150A0E1A5\r
+S21402B1B0014042E270A81B090600A0E153FFFFEB24\r
+S21402B1C0000054E30100C5E4014044E270A81B09F4\r
+S21402B1D0F8FFFFEA0DC0A0E10E002DE900D82DE928\r
+S21402B1E010B04CE204309BE5080053E30100000A6D\r
+S21402B1F00000A0E300A81BE950FFFFEBFBFFFFEAFD\r
+S21402B2000DC0A0E130D82DE964409FE504B04CE2C1\r
+S21402B210343094E50000E0E30FE0A0E103F0A0E1A3\r
+S21402B220343094E50050A0E10200E0E30FE0A0E134\r
+S21402B23003F0A0E1141094E538309FE538209FE52E\r
+S21402B240043081E534309FE5082081E50C3081E545\r
+S21402B2502C209FE52C309FE5102081E5143081E5F7\r
+S21402B260342094E50500A0E10FE0A0E102F0A0E1A1\r
+S21402B27030A81BE95000000058B1020098B1020045\r
+S21402B28010B1020010AF0200D4B102000DC0A0E15E\r
+S21402B29000D82DE930209FE504B04CE20030D2E51C\r
+S21402B2A00200E0E3000053E300A81B190130A0E30C\r
+S21402B2B00030C2E514209FE5343092E50FE0A0E1AD\r
+S21402B2C003F0A0E100681BE9CCFFFFEA04320300AA\r
+S21402B2D0500000000DC0A0E100D82DE94C209FE5EB\r
+S21402B2E0FF0000E2143092E50010A0E1000053E3F4\r
+S21402B2F0183092050010A00104B04CE2000093E55D\r
+S21402B3000C3093E50FE0A0E103F0A0E11C209FE5DE\r
+S21402B3100010A0E3443092E50100A0E1010053E1F1\r
+S21402B32000A81B09441082E500681BE9820000EAB7\r
+S21402B330500000000DC0A0E100D82DE944009FE5B2\r
+S21402B34004B04CE2182090E5003090E50338A0E106\r
+S21402B3502338A0E10C3043E2330053E300A81B89F4\r
+S21402B3604130A0E3000052E30510A0E3003080E580\r
+S21402B37000A81B09000092E5143092E50FE0A0E158\r
+S21402B38003F0A0E100A81BE9500000000DC0A0E1F8\r
+S21402B39010D82DE95C309FE504B04CE204D04DE2B3\r
+S21402B3A00040A0E318C093E50020A0E104005CE1A1\r
+S21402B3B00130A0E114400BE514104BE20700000A2E\r
+S21402B3C000009CE518C09CE50FE0A0E10CF0A0E1AF\r
+S21402B3D014301BE50040A0E1000053E30100001A10\r
+S21402B3E00400A0E110A81BE90C309FE5000093E5DD\r
+S21402B3F0510000EBF9FFFFEA50000000E082030074\r
+S21402B4000DC0A0E1D8109FE5D8209FE530D82DE9E1\r
+S21402B4100030A0E304B04CE2032181E7013083E26E\r
+S21402B4203F0053E3FBFFFFDAB4109FE5B8309FE519\r
+S21402B430B8209FE5003081E5B4309FE5402081E5E5\r
+S21402B440483081E5AC209FE5AC309FE50000A0E3E4\r
+S21402B450A8409FE58CE09FE5202081E500C0A0E1A2\r
+S21402B4601C3081E54C0081E5380081E50020A0E330\r
+S21402B4708C11A0E1023081E0012082E2070052E353\r
+S21402B48003E184E7FAFFFFDA01C08CE201005CE325\r
+S21402B490F5FFFFDA68309FE568209FE540409FE5AC\r
+S21402B4A00150E0E3303084E50500A0E1342084E575\r
+S21402B4B032FEFFEB0500A0E16DFEFFEB111300EB81\r
+S21402B4C00000A0E32DFEFFEB0000A0E368FEFFEB0A\r
+S21402B4D034209FE50030A0E3443084E58C2084E5E8\r
+S21402B4E030A81BE95000000078AD020016000800E4\r
+S21402B4F070AD020064AD020008AF02000CAF02009D\r
+S21402B500985D030080AD020074AE0200A4FB020048\r
+S21402B510000051E30600000A011041E20130D0E7C4\r
+S21402B520030053E30100A0030EF0A001000051E364\r
+S21402B530F8FFFF1A0000A0E30EF0A0E10DC0A0E1A4\r
+S21402B54000D82DE940309FE50120A0E3002083E5E6\r
+S21402B55038309FE5000050E304B04CE230009F050F\r
+S21402B5603C0090158C2093E50FE0A0E102F0A0E1EC\r
+S21402B57014309FE5002093E5000052E3012042E2EA\r
+S21402B580002083E500A81BD9F8FFFFEA008303002A\r
+S21402B5905000000070B502000DC0A0E130D82DE9C1\r
+S21402B5A080209FE504B04CE2003092E50040A0E126\r
+S21402B5B00338A0E12338A0E1410053E30150A0E1A3\r
+S21402B5C000C0E0E30D00000A0C0054E10510A0E103\r
+S21402B5D00400A0E10500000A0400A0E10510A0E1B5\r
+S21402B5E030F6FFEB0030A0E10300A0E130A81BE933\r
+S21402B5F065FFFFEB003050E2FAFFFF1AF5FFFFEAA5\r
+S21402B600183092E50610A0E3000053E3EDFFFF0AB0\r
+S21402B610000093E5143093E50FE0A0E103F0A0E10B\r
+S21402B62000C0A0E1E7FFFFEA500000000DC0A0E165\r
+S21402B63010D82DE9FF4000E20A0054E304B04CE2C1\r
+S21402B6400D00A0E30200000A0400A0E110681BE956\r
+S21402B6501FFFFFEA1EFFFFEBFAFFFFEA04E02DE5FD\r
+S21402B660FF0000E204E09DE4EFFFFFEA04309FE5FE\r
+S21402B670000083E50EF0A0E1083203000DC0A0E151\r
+S21402B68010D82DE90040A0E10000D0E504B04CE25D\r
+S21402B690000050E310A81B09FF0000E2E2FFFFEBE8\r
+S21402B6A00100F4E5000050E310A81B09F9FFFFEAC9\r
+S21402B6B00DC0A0E100D82DE904B04CE200C0A0E322\r
+S21402B6C004D04DE20C30A0E11010A0E32B20A0E342\r
+S21402B6D000C08DE54B0000EB00A81BE90DC0A0E101\r
+S21402B6E0F0DF2DE904B04CE224D04DE20160A0E187\r
+S21402B6F00050A0E104C09BE54C300BE500005CE383\r
+S21402B7002070A0033070A01328304BE21F40A0E345\r
+S21402B710014054E2207043E5013083E2FBFFFF5A0A\r
+S21402B720063095E10040A0E33030A00301408402D9\r
+S21402B73048304B051700000A063095E11500000A4E\r
+S21402B7400280A0E10090A0E328A04BE20930A0E12D\r
+S21402B7500820A0E10610A0E10500A0E1CE1500EB4E\r
+S21402B7609C209FE5014084E200C0D2E70610A0E1DB\r
+S21402B7700500A0E10930A0E10820A0E120C04AE5CA\r
+S21402B7803A1400EB0160A0E10050A0E1063090E11F\r
+S21402B79001A08AE2ECFFFF1A08309BE54C201BE56D\r
+S21402B7A0030054E10340A0B12D0052E301404412CD\r
+S21402B7B00900000A000054E3F0AF1BB928204BE250\r
+S21402B7C0023084E0200053E5014044E296FFFFEB9E\r
+S21402B7D0000054E3F0AF1BB9F7FFFFEA28304BE254\r
+S21402B7E0042083E0213052E5070053E128304B0263\r
+S21402B7F001404402042083004C301BE5203042E521\r
+S21402B800EBFFFFEAAC2003000DC0A0E170D82DE9E3\r
+S21402B81004B04CE208D04DE201C0A0E10260A0E113\r
+S21402B8200040A0E10050A0E30C20A0E104C09BE58C\r
+S21402B83003E0A0E10510A0E10400A0E10630A0E1CB\r
+S21402B84000E08DE504C08DE5A3FFFFEB70A81BE9C1\r
+S21402B85000C0A0E1000050E304E02DE50100A0E3F3\r
+S21402B8600C00A00104F09D040030DCE50C10A0E101\r
+S21402B870000053E304F09D0448E09FE5FF2003E246\r
+S21402B88001306CE00E0053E10000A0A30D0052E36D\r
+S21402B8900A0052130400000A080052E3203042E273\r
+S21402B8A00100000A5E0053E30000A083000050E39C\r
+S21402B8B0011081E204F09D040030D1E5000053E35C\r
+S21402B8C004F09D04ECFFFFEA010800000DC0A0E1B1\r
+S21402B8D0F0DF2DE90150A0E10040A0E1051094E15F\r
+S21402B8E004B04CE250D04DE23030A00378604BE218\r
+S21402B8F00270A0E100A0A0E377604B0278304B050F\r
+S21402B9001500000A052094E11300000A0380A0E156\r
+S21402B910C89FA0E10930A0E10820A0E10510A0E13F\r
+S21402B9200400A0E15C1500EB04309BE5000083E018\r
+S21402B9300030D0E50510A0E10400A0E10130C6E425\r
+S21402B9400930A0E10820A0E1C81300EB0150A0E1F5\r
+S21402B9500040A0E1051094E1EDFFFF1A78204BE2CB\r
+S21402B960020056E10500000A013076E578104BE247\r
+S21402B970010056E101A08AE20130C7E4F9FFFF1A8E\r
+S21402B9800030A0E30030C7E50A00A0E1F0AF1BE9F3\r
+S21402B9900DC0A0E1F0DF2DE904B04CE26CD04DE220\r
+S21402B9A00260A0E16C000BE50200A0E10190A0E1BC\r
+S21402B9B070300BE5A5FFFFEB0080A0E3000050E32C\r
+S21402B9C00020A0E30010A0E368004BE280304BE2C8\r
+S21402B9D078000BE5060003E90870A0E11102000AF0\r
+S21402B9E00020D6E50110D6E4000052E3FF5001E243\r
+S21402B9F00C00000A250055E30C00000A0500A0E131\r
+S21402BA000910A0E16C201BE50FE0A0E102F0A0E126\r
+S21402BA10018088E20020D6E50110D6E4000052E359\r
+S21402BA20FF5001E2F2FFFF1A0800A0E1F0AF1BE9A7\r
+S21402BA300130D6E400C0A0E3FF5003E22D0055E338\r
+S21402BA4080C00BE50130D6040140A003FF5003027C\r
+S21402BA5080400B05300055E30130D60401E0A00318\r
+S21402BA60FF500302303045E27CE00B057CC00B152C\r
+S21402BA70090053E30C00A0E10CA0A0E10700008A35\r
+S21402BA800110D6E40A218AE0822085E0FF5001E216\r
+S21402BA90303045E2090053E330A042E2F7FFFF9A56\r
+S21402BAA02E0055E3D101000A0020A0E36C0055E306\r
+S21402BAB074200BE5C501000A7A0055E30130D6046E\r
+S21402BAC0FF500302423045E2360053E303F19F97EC\r
+S21402BAD0440000EAB0BB0200E8BB0200B0BB0200B2\r
+S21402BAE0E8BB0200E8BB0200E8BB0200E8BB0200BB\r
+S21402BAF0E8BB0200E8BB0200E8BB0200E8BB0200AB\r
+S21402BB00E8BB0200E8BB0200E8BB0200E8BB02009A\r
+S21402BB10E8BB0200E8BB0200E8BB0200E8BB02008A\r
+S21402BB20B0BB0200E8BB0200E8BB0200B0BB0200EA\r
+S21402BB30E8BB0200E8BB0200E8BB0200E8BB02006A\r
+S21402BB40E8BB0200E8BB0200E8BB0200E8BB02005A\r
+S21402BB50E8BB0200B0BB0200E8BB0200B0BB0200BA\r
+S21402BB60E8BB0200E8BB0200E8BB0200E8BB02003A\r
+S21402BB70E8BB0200E8BB0200E8BB0200E8BB02002A\r
+S21402BB80E8BB0200E8BB0200E8BB0200B0BB020052\r
+S21402BB90E8BB0200E8BB0200E8BB0200E8BB02000A\r
+S21402BBA0B0BB0200E8BB0200E8BB0200B0BB02006A\r
+S21402BBB0000050E37C01000A70301BE580404BE237\r
+S21402BBC0060093E808E083E2060004E970E00BE56D\r
+S21402BBD0440055E3640055136B01001A84101BE5FC\r
+S21402BBE0000051E3600100BA253045E2530053E3FA\r
+S21402BBF003F19F974F0100EAF8BF020038C1020026\r
+S21402BC0038C1020038C1020038C1020038C1020041\r
+S21402BC1038C1020038C1020038C1020038C1020031\r
+S21402BC2038C1020038C1020038C1020038C1020021\r
+S21402BC3038C1020038C1020038C1020038C1020011\r
+S21402BC4038C1020038C1020038C1020038C1020001\r
+S21402BC5038C1020038C1020038C1020038C10200F1\r
+S21402BC6038C1020038C1020038C1020018C0020002\r
+S21402BC7084C002007CBD020038C1020038C1020046\r
+S21402BC8038C1020038C1020038C1020038C10200C1\r
+S21402BC9038C1020038C1020038C1020038C10200B1\r
+S21402BCA038C1020038C1020038C1020038C10200A1\r
+S21402BCB0B0C0020038C102007CBD020038C10200DA\r
+S21402BCC038C102007CBD020038C1020038C1020041\r
+S21402BCD038C1020038C1020038C1020038C1020071\r
+S21402BCE038C1020038C1020038C1020018C0020082\r
+S21402BCF084C002007CBD020038C1020038C10200C6\r
+S21402BD0038C1020038C1020038C1020038C1020040\r
+S21402BD1038C1020038C1020038C1020038C1020030\r
+S21402BD2038C1020048BD020038C1020038C1020014\r
+S21402BD30B0C0020038C102007CBD020038C1020059\r
+S21402BD4038C102007CBD02003000A0E30910A0E169\r
+S21402BD506C201BE50FE0A0E102F0A0E10140A0E3A9\r
+S21402BD607800A0E30910A0E16C301BE50FE0A0E12B\r
+S21402BD7003F0A0E108A0A0E37C400BE5443045E2D6\r
+S21402BD80340053E303F19F973C0000EA60BE0200D2\r
+S21402BD9080BE020080BE020080BE020080BE02009C\r
+S21402BDA080BE020080BE020080BE020080BE02008C\r
+S21402BDB080BE020080BE020080BE020080BE02007C\r
+S21402BDC080BE020080BE020080BE020080BE02006C\r
+S21402BDD060BE020080BE020080BE0200C8BF020033\r
+S21402BDE080BE020080BE020080BE020080BE02004C\r
+S21402BDF080BE020080BE020080BE020080BE02003C\r
+S21402BE0080BE020080BE020080BE020060BE02004B\r
+S21402BE1080BE020080BE020080BE020080BE02001B\r
+S21402BE2080BE020080BE020080BE020080BE02000B\r
+S21402BE3080BE020080BE020080BE0200E0BF02009A\r
+S21402BE4080BE020080BE020080BE020080BE0200EB\r
+S21402BE5060BE020080BE020080BE0200E0BF02009A\r
+S21402BE6080C04BE203001CE924C49FE568204BE235\r
+S21402BE700A30A0E300C08DE593FEFFEB0070A0E160\r
+S21402BE8068304BE2014047E278300BE590400BE524\r
+S21402BE9074001BE57C101BE5000050E30A4067E0D7\r
+S21402BEA001404412000051E32050A0030300000AA0\r
+S21402BEB074201BE53050A0E3000052E33800001A5D\r
+S21402BEC080E01BE500005EE30B00001A000054E36E\r
+S21402BED0014044E2080000DA0500A0E10910A0E1F2\r
+S21402BEE06C201BE50FE0A0E102F0A0E1000054E3A5\r
+S21402BEF0018088E2014044E2F6FFFFCA74301BE587\r
+S21402BF00000053E31F00001A000057E390701BE581\r
+S21402BF100C0000DA78E01BE50910A0E10130DEE44F\r
+S21402BF206C201BE5FF5003E278E00BE50500A0E17C\r
+S21402BF300FE0A0E102F0A0E1000057E3018088E2F2\r
+S21402BF40017047E2F2FFFFCA80301BE5000053E3B0\r
+S21402BF50AFFEFF0A000054E3014044E2ACFEFFDA03\r
+S21402BF602000A0E30910A0E16CC01BE50FE0A0E1F1\r
+S21402BF700CF0A0E1000054E3018088E2014044E2B4\r
+S21402BF80F6FFFFCAA2FEFFEA0300A0E10910A0E145\r
+S21402BF906CC01BE50FE0A0E10CF0A0E1018088E296\r
+S21402BFA0D8FFFFEA0200A0E10910A0E16C301BE511\r
+S21402BFB00FE0A0E103F0A0E1018088E200C0A0E368\r
+S21402BFC074C00BE5BDFFFFEA80204BE2C4C29FE5CA\r
+S21402BFD0030012E91030A0E368204BE2A4FFFFEA58\r
+S21402BFE080E04BE203001EE9ACC29FE568204BE20C\r
+S21402BFF01030A0E39EFFFFEA2500A0E30910A0E1AF\r
+S21402C0006C201BE50FE0A0E102F0A0E1013047E260\r
+S21402C01090300BE59DFFFFEA00705AE20200001A1C\r
+S21402C020000050E32070A0034070A01301E047E236\r
+S21402C0300040A0E30E0054E190E00BE58CE00BE537\r
+S21402C0400C0000AA68504BE280304BE2030013E972\r
+S21402C0500420A0E1F11100EB010010E33130A0E36F\r
+S21402C0602E30A0030130C5E48CC01BE5014084E2FB\r
+S21402C0700C0054E1F3FFFFBA68E04BE278E00BE510\r
+S21402C08082FFFFEA70301BE50910A0E10050D3E5FD\r
+S21402C0906C401BE50500A0E10FE0A0E104F0A0E182\r
+S21402C0A070C01BE504C08CE270C00BE557FEFFEAC9\r
+S21402C0B070301BE570C01BE5003093E504C08CE2CF\r
+S21402C0C0000053E3D4E19F0578300BE570C00BE522\r
+S21402C0D078E00B050300000A78001BE5DBFDFFEBAA\r
+S21402C0E0000050E30C00000A78101BE50070A0E385\r
+S21402C0F00730D1E7070053E100E0E00390E00B05CC\r
+S21402C10062FFFF0A78201BE5017087E20730D2E75C\r
+S21402C110000053E3FAFFFF1ABBFFFFEA80019FE528\r
+S21402C12055FDFFEB78001BE560FDFFEB74019FE514\r
+S21402C13078000BE5EBFFFFEA2500A0E30910A0E17B\r
+S21402C1406C401BE50FE0A0E104F0A0E10500A0E1D1\r
+S21402C1500910A0E10FE0A0E104F0A0E1028088E26D\r
+S21402C16001C047E290C00BE548FFFFEA80404BE281\r
+S21402C1700C0014E92DC0A0E3002072E20030E3E2D6\r
+S21402C1800C0004E974C00BE596FEFFEA80C04BE2A1\r
+S21402C19006001CE9F0308FE2180093E8031001E075\r
+S21402C1A0042002E006000CE98EFEFFEA70301BE572\r
+S21402C1B080E04BE2002093E5041083E20230A0E127\r
+S21402C1C0C34FA0E118000EE970100BE57FFEFFEAF0\r
+S21402C1D00130D6E401C0A0E3FF5003E26C0055E351\r
+S21402C1E00130D6040C00A001FF50030231FEFFEA24\r
+S21402C1F00120D6E47C101BE5FF5002E2303045E217\r
+S21402C200011081E2090053E37C100BE525FEFF8A4C\r
+S21402C2100130D6E4FF5003E2302045E2090052E343\r
+S21402C220FAFFFF9A1FFEFFEA7C009FE512FDFFEB76\r
+S21402C2300600A0E11DFDFFEB70009FE50740A0E3AE\r
+S21402C2400DFDFFEB2000A0E3F7FCFFEB70301BE5D3\r
+S21402C250002093E504C083E20200A0E10010A0E300\r
+S21402C26080304BE2030003E988001BE570C00BE553\r
+S21402C2700EFDFFEB014054E2F1FFFF5A30009FE54E\r
+S21402C280FDFCFFEB0000A0E3F0AF1BE9FFFFFFFFA2\r
+S21402C29000000000C0200300AC200300CC200300F6\r
+S21402C2A0E0200300E8200300401C0300FC200300FB\r
+S21402C2B014210300182103000C0091E9020053E147\r
+S21402C2C001C0A0E1FF0000E20EF0A0A1003091E55F\r
+S21402C2D00100C3E4003081E50010A0E30010C3E5CE\r
+S21402C2E008209CE5012082E208208CE50EF0A0E101\r
+S21402C2F00DC0A0E10E002DE900D82DE910B04CE2E9\r
+S21402C3000CD04DE200C0A0E101EBA0E318C00BE5A3\r
+S21402C31018104BE200C0A0E304209BE508308BE235\r
+S21402C32010009FE514E00BE510C00BE597FDFFEB50\r
+S21402C33010001BE500A81BE9B8C202000DC0A0E170\r
+S21402C3400F002DE900D82DE918309FE514B04CE215\r
+S21402C350000093E504209BE508308BE20010A0E382\r
+S21402C3608AFDFFEB00A81BE90832030004E02DE576\r
+S21402C37014309FE50020A0E1000093E50130A0E123\r
+S21402C3800010A0E304E09DE480FDFFEA083203000B\r
+S21402C3900DC0A0E1010052E1F0D92DE90260A0E152\r
+S21402C3A002606180000056E304B04CE20170A0E136\r
+S21402C3B00050A0E10380A0E1F0A91BD9000058E3D9\r
+S21402C3C007106810C0009F15BC009F050710A0014B\r
+S21402C3D00FE0A0E105F0A0E10040A0E3060054E172\r
+S21402C3E0A8009FE5240000AA0410D7E70FE0A0E10A\r
+S21402C3F005F0A0E1070054E394009FE51B00000A45\r
+S21402C400014084E20F0054E3F3FFFFDA84009FE565\r
+S21402C4100FE0A0E105F0A0E10040A0E3060054E131\r
+S21402C4202010A0A3030000AA0410D7E7203041E2A0\r
+S21402C4305E0053E32E10A0835C009FE5014084E279\r
+S21402C4400FE0A0E105F0A0E10F0054E3F2FFFFDAEF\r
+S21402C45048009FE5106046E20FE0A0E105F0A0E18B\r
+S21402C460000056E3107087E2F0A91BD9D2FFFFEA5C\r
+S21402C4700FE0A0E105F0A0E1E0FFFFEA20009FE563\r
+S21402C4800FE0A0E105F0A0E1D9FFFFEA1C210300BE\r
+S21402C490242103004C2103002C2103003021030039\r
+S21402C4A0342103003821030010402DE900C0A0E12A\r
+S21402C4B00140A0E110009FE50230A0E10C10A0E1CF\r
+S21402C4C00420A0E11040BDE8B0FFFFEA3CC3020032\r
+S21402C4D004E02DE50020A0E304E09DE4F1FFFFEA7E\r
+S21402C4E00DC0A0E1000051E1F0D92DE90150A0E114\r
+S21402C4F001506080000055E304B04CE20060A0E109\r
+S21402C5000280A0E1F0A91BD9000058E306106810CB\r
+S21402C5105C009F1558009F050610A00186FFFFEBE2\r
+S21402C520C53FA0E1237F85E00040A0E3470154E138\r
+S21402C53040009FE50B0000AA041196E77EFFFFEB82\r
+S21402C540014084E2030054E3F7FFFFDA28009FE588\r
+S21402C550105045E278FFFFEB000055E3106086E2DC\r
+S21402C560F0A91BD9E7FFFFEA10009FE572FFFFEB79\r
+S21402C570F2FFFFEA1C2103003C2103008023030094\r
+S21402C5804421030004E02DE50020A0E304E09DE43E\r
+S21402C590D2FFFFEA0DC0A0E1000051E1F0D92DE97B\r
+S21402C5A00150A0E101506080000055E304B04CE267\r
+S21402C5B00060A0E10280A0E1F0A91BD9000058E3C8\r
+S21402C5C0061068106C009F1568009F050610A001F3\r
+S21402C5D059FFFFEB0040A0E3C57FA0E1A73F85E03F\r
+S21402C5E0C30054E150009FE58420A0E14C009FA5C3\r
+S21402C5F00E0000AAB61092E14FFFFFEB030054E3D1\r
+S21402C6003C009FE50900000A014084E2070054E36B\r
+S21402C610F1FFFFDA2C009FE5105045E246FFFFEBE4\r
+S21402C620000055E3106086E2F0A91BD9E2FFFFEA9C\r
+S21402C63041FFFFEBF3FFFFEA1C210300502103003A\r
+S21402C640482103004C2103008023030004E02DE56B\r
+S21402C6500020A0E304E09DE4CDFFFFEA14309FE54E\r
+S21402C66004E02DE5030051E10100500304F09D149F\r
+S21402C67004E09DE404FBFFEA7427000004E02DE5D5\r
+S21402C68008109FE50100A0E304E09DE4F2FFFFEA44\r
+S21402C69074270000030052E302C0A0E104E02DE587\r
+S21402C6A00020A0E10200009A003081E1030013E3BB\r
+S21402C6B00800000A01C04CE201007CE304F09D047D\r
+S21402C6C00130D1E401C04CE201007CE30130C2E457\r
+S21402C6D004F09D04F9FFFFEA0F005CE300E0A0E12E\r
+S21402C6E00A00009A043091E410C04CE204308EE452\r
+S21402C6F0042091E40F005CE304208EE4043091E40D\r
+S21402C70004308EE4042091E404208EE4F4FFFF8AD1\r
+S21402C71003005CE30400009A043091E404C04CE297\r
+S21402C72003005CE304308EE4FAFFFF8A01C04CE2A9\r
+S21402C73001007CE30E20A0E104F09D040130D1E468\r
+S21402C74001C04CE201007CE30130C2E404F09D0427\r
+S21402C750F9FFFFEA0EF0A0E10DC0A0E100D82DE936\r
+S21402C76058309FE504B04CE2380093E5F2FEFFEB4A\r
+S21402C7704C109FE54C309FE54C209FE54C009FE512\r
+S21402C780EDFEFFEB48009FE5EBFEFFEB44309FE536\r
+S21402C79044009FE5001093E5002090E53C009FE5ED\r
+S21402C7A0E5FEFFEB38309FE538009FE5060093E88C\r
+S21402C7B0E1FEFFEB30009FE500681BE9DEFEFFEAC4\r
+S21402C7C05000000000220300681B0300082203003A\r
+S21402C7D01022030028220300008403004083030083\r
+S21402C7E058220300608403006822030070220300BC\r
+S21402C7F00DC0A0E170D82DE92C309FE52C409FE5B6\r
+S21402C80004B04CE2030054E10050A0E170A81B09FA\r
+S21402C8100360A0E10500A0E10FE0A0E104F094E4CB\r
+S21402C820060054E170A81B09F9FFFFEAF033030083\r
+S21402C830F03303000DC0A0E110D82DE9FF4000E25E\r
+S21402C8400A0054E304B04CE20D00A0E30200000A22\r
+S21402C8500400A0E110681BE98E0200EA8D0200EBDC\r
+S21402C860FAFFFFEA04E02DE508009FE50110A0E3C9\r
+S21402C87004E09DE4CF0900EA445F03000DC0A0E196\r
+S21402C880F0DF2DE9FC229FE5FC429FE5FC329FE5A6\r
+S21402C89004B04CE204D04DE2F4029FE50050E0E31F\r
+S21402C8A0383084E5542084E56FFBFFEB76FAFFEB25\r
+S21402C8B0343094E50500A0E10FE0A0E103F0A0E12A\r
+S21402C8C00060A0E3343094E50090A0E10600A0E109\r
+S21402C8D00FE0A0E103F0A0E1B8229FE5B8329FE5A1\r
+S21402C8E00170A0E3006083E5007082E5483094E5BD\r
+S21402C8F0A8029FE50FE0A0E103F0A0E1A0329FE5C9\r
+S21402C900A0229FE5A0029FE50117A0E3006083E551\r
+S21402C910001082E594329FE594229FE501C760E20B\r
+S21402C92000C083E5005082E588329FE588229FE5B5\r
+S21402C930001083E5000082E580329FE50FE0A0E16B\r
+S21402C94003F0A0E178429FE578329FE5030054E1C8\r
+S21402C9500400000A0350A0E10FE0A0E104F094E412\r
+S21402C960050054E1FBFFFF1A4C329FE534229FE597\r
+S21402C970004093E500C092E54C329FE50000A0E33C\r
+S21402C9800010A0E1101083E872FFFFEB3C829FE5E7\r
+S21402C9902CA04BE2000057E30200000A30029FE59B\r
+S21402C9A065FEFFEB0070A0E328429FE50150A0E37E\r
+S21402C9B00400A0E1011CA0E30A20A0E3005088E5E1\r
+S21402C9C0120500EB0030A0E3010070E30060A0E176\r
+S21402C9D0003088E5EEFFFF0A030050E13500000A4A\r
+S21402C9E00400A0E1011CA0E33C0800EB0030D4E503\r
+S21402C9F02C400BE53D0053E3230053130700001AB7\r
+S21402CA003D0053E30100000A0170A0E3E0FFFFEAE5\r
+S21402CA10021084E2C0019FE547FEFFEBF9FFFFEA42\r
+S21402CA20000053E3F7FFFF0AB0619FE5B0519FE5B0\r
+S21402CA300610A0E10520A0E10A00A0E1AE0500EB89\r
+S21402CA400040A0E1000054E398019FE51500000AAB\r
+S21402CA5094319FE594219FE5003082E5520900EB70\r
+S21402CA600030A0E1000053E384019FE50510A0E139\r
+S21402CA700800000A30FEFFEB70319FE50020A0E3BD\r
+S21402CA80002083E52C301BE50020D3E5000052E3AE\r
+S21402CA90E6FFFF1ADBFFFFEA000096E50FE0A0E1E3\r
+S21402CAA00CF094E5F3FFFFEA001095E544019FE5DC\r
+S21402CAB021FEFFEBF2FFFFEACC309FE5342093E540\r
+S21402CAC034319FE5005083E50FE0A0E102F0A0E1DB\r
+S21402CAD0B4209FE50410A0E3143092E5000093E52D\r
+S21402CAE0142093E50FE0A0E102F0A0E198309FE564\r
+S21402CAF00900A0E1342093E50FE0A0E102F0A0E1F6\r
+S21402CB00A0309FE50600A0E1002093E50F10C2E3E7\r
+S21402CB1050E041E200018EE7010080E20A0050E3A5\r
+S21402CB20FBFFFFDAD4309FE578C09FE5D0209FE573\r
+S21402CB3000308EE51330A0E334108EE53C208EE5FF\r
+S21402CB4040308EE50C00A0E138208EE500E08CE552\r
+S21402CB50B0109FE5050900EB2C409FE598309FE555\r
+S21402CB600020A0E3002083E5301094E50000E0E317\r
+S21402CB700FE0A0E101F0A0E1343094E50FE0A0E17F\r
+S21402CB8003F0A0E182FFFFEA7CCD02005000000025\r
+S21402CB90D030030034C80200208403002083030040\r
+S21402CBA0400D030000840300A084030008850300F0\r
+S21402CBB0E083030040840300408303008084030074\r
+S21402CBC054C70200F0330300F0330300608403000E\r
+S21402CBD0008503007C2203003C5E03006020030005\r
+S21402CBE0C083030060830300445F030064C802003E\r
+S21402CBF0F431030088220300B4220300C084030039\r
+S21402CC00B08E02004CCD02003C5F03000DC0A0E1D6\r
+S21402CC10F0D92DE9000052E304B04CE204D04DE214\r
+S21402CC200250A0E10040A0E10160A0E10370A0E193\r
+S21402CC300080A0E30200000A0200A0E11C0800EB4C\r
+S21402CC400080A0E1060054E1F0A91B09000055E2AD\r
+S21402CC500820A0E10130A0E30400000A001094E5D9\r
+S21402CC60250100EB000050E30030A0130130A003C2\r
+S21402CC70000053E30720A0E144009FE50300001AEA\r
+S21402CC80184084E2060054E1F0A91B09EEFFFFEA11\r
+S21402CC90021094E9003094E500C08DE5A6FDFFEB96\r
+S21402CCA0100094E50020A0E3020050E102005511B6\r
+S21402CCB0F2FFFF0A141094E5003094E5D2FFFFEB72\r
+S21402CCC0EEFFFFEAD82203000DC0A0E130D82DE91E\r
+S21402CCD004B04CE20040A0E314E04BE20150A0E3B3\r
+S21402CCE050C09FE514D04DE20520A0E10430A0E13B\r
+S21402CCF004402EE504E08DE50CC08DE500408DE590\r
+S21402CD0008508DE5AE0500EB0020A0E1040052E1DC\r
+S21402CD1024009FE524109FE524309FE50100001AB9\r
+S21402CD2085FDFFEB30A81BE918009FE518201BE5E0\r
+S21402CD30B5FFFFEB30A81BE9E8220300F022030050\r
+S21402CD40F0330300681B0300A03203000DC0A0E10D\r
+S21402CD5010D82DE904B04CE200300FE100400FE19C\r
+S21402CD60C04084E304F029E10FE0A0E100F0A0E176\r
+S21402CD7000009FE5840800EB3C5F030018309FE547\r
+S21402CD800DC0A0E10020A0E100D82DE90C009FE52F\r
+S21402CD9004B04CE2002083E57B0800EB405F030012\r
+S21402CDA03C5F03000DC0A0E1F0D82DE928329FE5D4\r
+S21402CDB004B04CE224C29FE570D04DE20040A0E3EE\r
+S21402CDC064504BE200E093E500408CE570C04BE215\r
+S21402CDD000C08DE508C29FE50060A0E10170A0E1F9\r
+S21402CDE00500A0E17710A0E30120A0E30430A0E153\r
+S21402CDF07CE00BE574E04BE204E08DE508C08DE5CF\r
+S21402CE0078400BE5650500EBD8E19FE578C04BE27C\r
+S21402CE104C004BE26310A0E30420A0E10230A0E342\r
+S21402CE2000C08DE510408DE95C0500EB02C0A0E372\r
+S21402CE3000C08DE5B0C19FE57CE04BE20600A0E1B4\r
+S21402CE400710A0E10530A0E10120A0E304E08DE593\r
+S21402CE5008408DE50CC08DE5590500EB040050E155\r
+S21402CE60F0A81B097C101BE5010071E35700000ABD\r
+S21402CE7074301BE5000053E31100000A70201BE526\r
+S21402CE8068019FE5823262E0033182E08341A0E1DD\r
+S21402CE9029FDFFEB090054E3090000DA6C504BE26F\r
+S21402CEA00500A0E10810A0E30A20A0E3D70300EBE8\r
+S21402CEB0020070E30A4044E2F0A81B09090054E3AA\r
+S21402CEC0F6FFFFCA28419FE50000E0E3343094E510\r
+S21402CED00FE0A0E103F0A0E1343094E50050A0E1B9\r
+S21402CEE00000A0E30FE0A0E103F0A0E1146094E5E7\r
+S21402CEF00410A0E3000096E5143096E50FE0A0E1EA\r
+S21402CF0003F0A0E1343094E50500A0E10FE0A0E1D3\r
+S21402CF1003F0A0E1146094E50910A0E3000096E592\r
+S21402CF20143096E50FE0A0E103F0A0E100500FE117\r
+S21402CF3000400FE1C04084E304F029E1B4309FE5ED\r
+S21402CF400010A0E3002093E50F00C2E350E040E2A9\r
+S21402CF5001118EE7011081E20A0051E3FBFFFFDABE\r
+S21402CF607C301BE58CC09FE58C209FE500308EE56B\r
+S21402CF701330A0E334008EE53C208EE50C00A0E1E1\r
+S21402CF8038208EE540308EE500E08CE56C109FE59B\r
+S21402CF90F60700EB000096E50A10A0E3142096E5DB\r
+S21402CFA00FE0A0E102F0A0E100300FE1C04005E290\r
+S21402CFB0C030C3E3043083E103F029E140209FE55B\r
+S21402CFC040009FE5001092E5DBFCFFEBF0A81BE9B2\r
+S21402CFD034009FE5D8FCFFEBF0A81BE94084030071\r
+S21402CFE0F431030004230300142303002C2303005C\r
+S21402CFF04023030050000000A08403004CCD020032\r
+S21402D0003C5F0300405F030084230300A823030061\r
+S21402D0100DC0A0E110D82DE938409FE504B04CE2DF\r
+S21402D02034009FE5C4FCFFEB483094E52C009FE5F6\r
+S21402D0300FE0A0E103F0A0E124009FE5BEFCFFEBB9\r
+S21402D040403094E50FE0A0E103F0A0E114009FE574\r
+S21402D05010681BE9B8FCFFEA50000000C823030072\r
+S21402D060400D030080230300D823030028209FE5F9\r
+S21402D070003092E50010A0E3010073E30400000A0A\r
+S21402D080030050E10200003A043092E5030050E14A\r
+S21402D090011081320100A0E10EF0A0E160840300DD\r
+S21402D0A010402DE90040A0E10130D4E4FF0003E285\r
+S21402D0B0412040E2190052E3203080E2FF00039252\r
+S21402D0C00130D1E4FFC000E2FF3003E2412043E238\r
+S21402D0D0190052E320E083E2FF300E92FF0003E2E3\r
+S21402D0E000005CE10C0060101080BD1800005CE3DC\r
+S21402D0F00C00A001EBFFFF1A1080BDE8000052E30F\r
+S21402D10010402DE90040A0E102E0A0E10200A001EB\r
+S21402D1101080BD080130D4E4FF0003E2412040E263\r
+S21402D120190052E3203080E2FF0003920130D1E47E\r
+S21402D130FFC000E2FF0003E2412040E2203080E22E\r
+S21402D140190052E3FF000392FF0000E200005CE1D8\r
+S21402D1500C0060101080BD1800005CE30100000A9D\r
+S21402D16001E05EE2EAFFFF1A0000A0E31080BDE8DD\r
+S21402D1700DC0A0E1F0D82DE9F4609FE504B04CE2C2\r
+S21402D18004D04DE20040A0E1343096E50000E0E332\r
+S21402D1900150A0E10FE0A0E103F0A0E1020054E399\r
+S21402D1A00070A0E10C00000AC8009FE562FCFFEBDD\r
+S21402D1B0C4309FE5002093E5000052E30710A0115B\r
+S21402D1C0B8009F150200001AB4009FE55AFCFFEB58\r
+S21402D1D0F0A81BE958FCFFEBF0A81BE9040095E554\r
+S21402D1E0A0109FE50320A0E34A0600EB000050E3F0\r
+S21402D1F084309F05000083050300001A88309FE5EF\r
+S21402D2000120A0E3002083E5F0A81BE90020A0E3AC\r
+S21402D21020104BE2040095E50230A0E1180500EB71\r
+S21402D220000050E30410950560009F05E8FFFF0A22\r
+S21402D23020001BE5000050E30A00001A343096E591\r
+S21402D2400FE0A0E103F0A0E1302096E520001BE508\r
+S21402D2500FE0A0E102F0A0E120301BE5070053E159\r
+S21402D260E5FFFF1AF0A81BE9041095E520009FE5EC\r
+S21402D270D7FFFFEA50000000482403002083030083\r
+S21402D280682403006C240300702403002084030037\r
+S21402D29074240300942403000DC0A0E1F0D82DE905\r
+S21402D2A090309FE50020A0E1006093E504B04CE2D8\r
+S21402D2B0000056E380709FE50000E0E3FF5002E2C4\r
+S21402D2C00900000A143097E50510A0E1000053E3B8\r
+S21402D2D0183097050510A001000093E50C3093E581\r
+S21402D2E00FE0A0E103F0A0E1F0A81BE9343097E5D7\r
+S21402D2F00FE0A0E103F0A0E1343097E50040A0E1A2\r
+S21402D3000600A0E10FE0A0E103F0A0E1143097E5EB\r
+S21402D3100510A0E1000093E50C3093E50FE0A0E1D4\r
+S21402D32003F0A0E1342097E50400A0E10FE0A0E1BD\r
+S21402D33002F0A0E1F0A81BE92083030050000000E1\r
+S21402D3400DC0A0E110D82DE928209FE50040A0E1FD\r
+S21402D350143092E504B04CE2000053E31830920514\r
+S21402D360000093E5103093E50FE0A0E103F0A0E1A2\r
+S21402D3700000C4E510A81BE9500000000DC0A0E1A3\r
+S21402D380F0DD2DE910319FE50040A0E3002093E593\r
+S21402D39004B04CE2040052E10060A0E10E00000A74\r
+S21402D3A0F8209FE5143092E5000053E3183092050A\r
+S21402D3B0000093150010A0011C3093150000930581\r
+S21402D3C00610A0111C3093050FE0A0E103F0A0E1C7\r
+S21402D3D00040A0E10400A0E1F0AD1BE9BC709FE5AF\r
+S21402D3E00000E0E3343097E50FE0A0E103F0A0E1AF\r
+S21402D3F0AC309FE500A0A0E1002093E50450A0E138\r
+S21402D400020054E1150000AA0080A0E3343097E53C\r
+S21402D4100800A0E10FE0A0E103F0A0E1143097E5D8\r
+S21402D4200610A0E1000093E51C3093E50FE0A0E1B2\r
+S21402D43003F0A0E1080050E1015085E20040A0E1BF\r
+S21402D4400200000A0030D6E5080053E10900001A7F\r
+S21402D4504C309FE5002093E5020055E1E9FFFFBA54\r
+S21402D4600A00A0E134309FE5342093E50FE0A0E106\r
+S21402D47002F0A0E1D6FFFFEA1C309FE50120A0E300\r
+S21402D480002083E5301097E50800A0E10FE0A0E158\r
+S21402D49001F0A0E10800A0E1F1FFFFEA208303000B\r
+S21402D4A050000000845F03000DC0A0E1F0D82DE913\r
+S21402D4B0C4309FE5C4609FE5005093E50040A0E1BC\r
+S21402D4C0000055E304B04CE20670A0E10000E0E381\r
+S21402D4D01100000A143096E50710A0E3000053E39B\r
+S21402D4E00420A0E100009315143093150FE0A0115C\r
+S21402D4F003F0A011183097E50420A0E1000053E3E2\r
+S21402D5000710A0E3F0A81B09000093E5143093E58A\r
+S21402D5100FE0A0E103F0A0E1F0A81BE9343096E5A5\r
+S21402D5200FE0A0E103F0A0E154309FE50070A0E117\r
+S21402D530004083E50500A0E1343096E50FE0A0E167\r
+S21402D54003F0A0E1143096E50140A0E3000053E3A7\r
+S21402D5500710A0E30420A0E10000931514309315F1\r
+S21402D5600FE0A01103F0A011343096E50700A0E109\r
+S21402D5700FE0A0E103F0A0E1F0A81BE9208303007E\r
+S21402D58050000000845F03000DC0A0E1F0DF2DE92B\r
+S21402D5905C389FE504B04CE20CD04DE200A0A0E15E\r
+S21402D5A00070A0E10000D0E5003093E5000050E3F3\r
+S21402D5B030100BE50280A0E134300BE50090A0E3CA\r
+S21402D5C00500000A0030A0E1FF0003E231FFFFEB96\r
+S21402D5D00130F7E5000053E3FAFFFF1A0750A0E117\r
+S21402D5E00A0057E10030A0130130A003000058E300\r
+S21402D5F00030A0D3013003C2000053E3F901000A51\r
+S21402D600320058E30840A0B13240A0A30400A0E1D3\r
+S21402D610A4FFFFEB000058E3080000DA29604BE2A3\r
+S21402D6200600A0E154FFFFEB000050E30090A0E1EB\r
+S21402D630E901001A088064E0000058E3F7FFFFCA19\r
+S21402D640000059E3E001000A0030A0E30030C7E51D\r
+S21402D65029005BE5013040E20020A0E17E0053E3B2\r
+S21402D66003F19F97A80100EA3CD9020074D9020090\r
+S21402D67094D90200ACD9020010DA020030DA0200B5\r
+S21402D6800CDD020014DD02000CDD02009CDA020052\r
+S21402D6904CDA02000CDD02009CDA020080DB02009B\r
+S21402D6A00CDD020064D802000CDD02000CDD020074\r
+S21402D6B00CDD02000CDD02000CDD02000CDD0200B7\r
+S21402D6C00CDD02000CDD02000CDD02000CDD0200A7\r
+S21402D6D00CDD02000CDD02000CDD02000CDD020097\r
+S21402D6E00CDD02000CDD02000CDD02000CDD020087\r
+S21402D6F00CDD020010DC02000CDD02000CDD020074\r
+S21402D7000CDD02000CDD02000CDD02000CDD020066\r
+S21402D71010DC02000CDD02000CDD02000CDD020053\r
+S21402D7200CDD02000CDD02000CDD02000CDD020046\r
+S21402D7300CDD02000CDD02000CDD02000CDD020036\r
+S21402D7400CDD02000CDD02000CDD02000CDD020026\r
+S21402D7500CDD02000CDD02000CDD02000CDD020016\r
+S21402D7600CDD02000CDD02000CDD02000CDD020006\r
+S21402D7700CDD02000CDD02000CDD02000CDD0200F6\r
+S21402D7800CDD02000CDD02000CDD02000CDD0200E6\r
+S21402D7900CDD02000CDD02000CDD02000CDD0200D6\r
+S21402D7A00CDD02000CDD02000CDD02000CDD0200C6\r
+S21402D7B00CDD02000CDD02000CDD02000CDD0200B6\r
+S21402D7C00CDD02000CDD02000CDD02000CDD0200A6\r
+S21402D7D00CDD02000CDD02000CDD02000CDD020096\r
+S21402D7E00CDD02000CDD02000CDD02000CDD020086\r
+S21402D7F00CDD02000CDD02000CDD02000CDD020076\r
+S21402D8000CDD02000CDD02000CDD02000CDD020065\r
+S21402D8100CDD02000CDD02000CDD02000CDD020055\r
+S21402D8200CDD02000CDD02000CDD02000CDD020045\r
+S21402D8300CDD02000CDD02000CDD02000CDD020035\r
+S21402D8400CDD02000CDD02000CDD02000CDD020025\r
+S21402D8500CDD02000CDD02000CDD02000CDD020015\r
+S21402D86014DD020034101BE5000051E32D0000BA5F\r
+S21402D8700A0055E10800000A0800A0E385FEFFEB57\r
+S21402D8802000A0E383FEFFEB015045E20800A0E380\r
+S21402D89080FEFFEB0A0055E1F6FFFF1A34301BE567\r
+S21402D8A050159FE50A00A0E1031481E0DA0400EBBC\r
+S21402D8B00000D5E5000050E31400001A34101BE502\r
+S21402D8C00570A0E1011051E22C359F4534100BE59E\r
+S21402D8D00030934529005B4534300B450000004A72\r
+S21402D8E029005BE514659FE530101BE50000C6E5E0\r
+S21402D8F001208AE0013042E2030055E137FFFF1AB9\r
+S21402D9000030A0E3013042E530001BE5F0AF1BE932\r
+S21402D910FF0000E25FFEFFEB0100F5E5000050E3CA\r
+S21402D920FAFFFF1AE4FFFFEA0700A0E359FEFFEB47\r
+S21402D930C8649FE529005BE5EAFFFFEA0A0055E1B5\r
+S21402D9400800000A0A0057E1014047E20500000A03\r
+S21402D9500800A0E34FFEFFEB0A0054E1014044E258\r
+S21402D960FAFFFF1A29005BE590649FE50A50A0E1E2\r
+S21402D970DCFFFFEA0A0055E1D9FFFF0A0800A0E330\r
+S21402D98044FEFFEB74649FE529005BE5015045E227\r
+S21402D990D4FFFFEA68049FE567FAFFEB0030A0E3D6\r
+S21402D9A00100E0E30030CAE5F0AF1BE9070055E1ED\r
+S21402D9B0CBFFFF0A017047E2070055E10540A0E1F0\r
+S21402D9C00500000A0130D4E50130C4E4FF0003E29A\r
+S21402D9D030FEFFEB070054E1F9FFFF1A2000A0E338\r
+S21402D9E02CFEFFEB0800A0E32AFEFFEB050054E145\r
+S21402D9F0014044E2B9FFFF0A0800A0E325FEFFEB60\r
+S21402DA00050054E1014044E2FAFFFF1AB3FFFFEAC1\r
+S21402DA10070055E1B2FFFF0A0100D5E4FF0000E26D\r
+S21402DA201CFEFFEB070055E1FAFFFF1AABFFFFEA09\r
+S21402DA30070055E10100D514C0639F15FF000012D0\r
+S21402DA40A7FFFF0A13FEFFEBB9FFFFEA070055E147\r
+S21402DA50A3FFFF0A014085E22000A0E30DFEFFEBD4\r
+S21402DA60070054E1014084E2FAFFFF1A014044E253\r
+S21402DA70050054E10400000A0800A0E3014044E265\r
+S21402DA8004FEFFEB050054E1FAFFFF1A29005BE5EE\r
+S21402DA9068639FE50570A0E192FFFFEAFF2002E2BD\r
+S21402DAA00A0052E354639F152F00000A0D0052E34A\r
+S21402DAB00600001A0030D6E50A0053E30300001AF7\r
+S21402DAC00030A0E30300A0E129304BE585FFFFEA22\r
+S21402DAD030339FE5002093E5000052E31C00001A55\r
+S21402DAE024339FE50000C6E5002093E5000052E3DC\r
+S21402DAF00100001A0100A0E3F0AF1BE90A00A0E152\r
+S21402DB00050100EB0030DAE5000053E3F8FFFF0AF8\r
+S21402DB10DC229FE5E0129FE5003092E5D4029FE505\r
+S21402DB20013083E2100053E3003082E50030A003A8\r
+S21402DB3000308205002092E5003091E5020480E084\r
+S21402DB40030052E1002081C50A10A0E1320400EB76\r
+S21402DB50E7FFFFEA0D00A0E3CEFDFFEB0A00A0E31D\r
+S21402DB60CCFDFFEB29005BE5DCFFFFEA8C629FE55C\r
+S21402DB700030D6E50D0053E3CBFFFF1ACFFFFFEAD6\r
+S21402DB8034301BE5000053E366FFFFBA013083E240\r
+S21402DB9034300BE560329FE534101BE5002093E538\r
+S21402DBA0020051E10010A0C30A0055E134100BE553\r
+S21402DBB00800000A0800A0E3B6FDFFEB2000A0E381\r
+S21402DBC0B4FDFFEB015045E20800A0E3B1FDFFEB18\r
+S21402DBD00A0055E1F6FFFF1A34301BE514129FE5E2\r
+S21402DBE00A00A0E1031481E00B0400EB0000D5E577\r
+S21402DBF0000050E3A4FFFF0AFF0000E2A5FDFFEBD2\r
+S21402DC000100F5E5000050E3FAFFFF1A9EFFFFEA67\r
+S21402DC100A0055E13800000AE0619FE50030D6E5CB\r
+S21402DC205C0053E33400001A070055E10150450238\r
+S21402DC300570A0010500000A0800A0E395FDFFEBB1\r
+S21402DC4029305BE5013065E529005BE57CFFFFEAEC\r
+S21402DC50070055E10900000A050057E10030A0E37D\r
+S21402DC600740A0E10130E7E50300000A013054E571\r
+S21402DC70013044E4050054E1FBFFFF1A29005BE58E\r
+S21402DC8080319FE5002093E5000052E31600001A5B\r
+S21402DC90070055E11100000A0100C5E4070055E13E\r
+S21402DCA00540A0E10400000A0100D4E4FF0000E2FF\r
+S21402DCB078FDFFEB070054E1FAFFFF1A050054E176\r
+S21402DCC0014044E21AFFFF0A0800A0E371FDFFEBE1\r
+S21402DCD0050054E1014044E2FAFFFF1A14FFFFEA8E\r
+S21402DCE00100C5E429005BE569FFFFEAFF0000E2E8\r
+S21402DCF068FDFFEB29005BE5E4FFFFEAFF0002E2B6\r
+S21402DD00D4F1FFEB0000A0E3F0AF1BE9EC609FE567\r
+S21402DD10CEFFFFEA0A0055E1F1FEFF0A070055E1D1\r
+S21402DD201A00000A017047E2015045E20800A0E32B\r
+S21402DD3058FDFFEB070055E10540A0E10760A0E1B2\r
+S21402DD400500000A0130D4E50130C4E4FF0003E216\r
+S21402DD5050FDFFEB060054E1F9FFFF1A2000A0E396\r
+S21402DD604CFDFFEB0800A0E34AFDFFEB050054E183\r
+S21402DD70014044E2D9FEFF0A0800A0E345FDFFEB9E\r
+S21402DD80050054E1014044E2FAFFFF1AD3FEFFEA1F\r
+S21402DD9070309FE5002093E5000052E30200001A6F\r
+S21402DDA0017047E2015045E2CDFEFFEA0800A0E31B\r
+S21402DDB038FDFFEB2000A0E336FDFFEB0800A0E3F2\r
+S21402DDC034FDFFEB29005BE5F4FFFFEA0100A0E368\r
+S21402DDD086FAFFEB0000E0E3F0AF1BE90000A0E3E9\r
+S21402DDE082FAFFEB15FEFFEA29004BE253FDFFEB3A\r
+S21402DDF014FEFFEA0C320300885F030010320300B1\r
+S21402DE0014320300B82403002084030000850300B4\r
+S21402DE1004E02DE50030A0E30030C0E504E09DE418\r
+S21402DE20D8FDFFEA0DC0A0E110D82DE90130A0E12F\r
+S21402DE3004B04CE208D04DE20210A0E10040A0E19E\r
+S21402DE400300A0E148F9FFEB54009FE53AF9FFEB27\r
+S21402DE500420A0E118004BE20810A0E3EBFFFFEB62\r
+S21402DE60000050E3070000DA18205BE5590052E391\r
+S21402DE700030A0130130A003790052E30300A01182\r
+S21402DE800100830310A81BE9010070E314009FE55C\r
+S21402DE900100000A0000A0E310A81BE926F9FFEB28\r
+S21402DEA0FBFFFFEABC240300D02403000DC0A0E160\r
+S21402DEB00F002DE900D82DE914B04CE204109BE5C2\r
+S21402DEC008208BE20000A0E3D5FFFFEB00A81BE9C9\r
+S21402DED000C0D0E530304CE2090053E30010A0E366\r
+S21402DEE00C20A0E10800008A01C0F0E5013181E0C3\r
+S21402DEF0FF2002E230104CE2832082E0090051E368\r
+S21402DF00301042E20C20A0E1F6FFFF9AFF001CE36D\r
+S21402DF100100A0010000E0130EF0A0E10DC0A0E198\r
+S21402DF20F0DD2DE900719FE50030D0E5002097E591\r
+S21402DF30210053E304B04CE20040A0E1016082E21B\r
+S21402DF40F0AD1B190130D0E5000053E3F0AD1B091C\r
+S21402DF50000056E3240000DA0320A0E3CC109FE57D\r
+S21402DF60EC0200EB000050E32900000A018084E284\r
+S21402DF700800A0E1D5FFFFEB000050E30050A0E14F\r
+S21402DF80050000BA003097E5030050E1A0109FD5C7\r
+S21402DF900400A0D1051481D01B0000DA0800A0E11D\r
+S21402DFA0430300EB8C309FE5000056E300A0A0E19F\r
+S21402DFB0005093E50C0000DA74309FE50810A0E1EB\r
+S21402DFC0057483E00700A0E10A20A0E15C0300EBF1\r
+S21402DFD0000050E30A00000A015055E248309F450F\r
+S21402DFE000509345016056E2F2FFFF1A0410A0E1CA\r
+S21402DFF044009FE5D0F8FFEB0030A0E30030C4E514\r
+S21402E000F0AD1BE90400A0E10710A0E1F06D1BE9EA\r
+S21402E010010300EA1C309FE514109FE5002093E5FB\r
+S21402E0200400A0E1021481E0F7FFFFEA10320300C9\r
+S21402E030E0240300885F03000C320300E42403009C\r
+S21402E0400DC0A0E170D82DE99C309FE59C209FE58D\r
+S21402E050001093E5003092E504B04CE2010053E173\r
+S21402E060016081E21300000A80309FE50050A0E3C1\r
+S21402E070002093E5060055E1014082E270A81BA944\r
+S21402E0806C209FE50510A0E1042482E064009FE571\r
+S21402E090A9F8FFEB50309FE5014084E2002093E5AB\r
+S21402E0A0015085E2020054E10040A0C3060055E19B\r
+S21402E0B070A81BA9F1FFFFEA0050A0E3060055E195\r
+S21402E0C070A81BA928409FE50510A0E10420A0E146\r
+S21402E0D020009FE5015085E297F8FFEB060055E128\r
+S21402E0E0014C84E270A81BA9F6FFFFEA1032030077\r
+S21402E0F00C320300885F0300FC2403000DC0A0E17D\r
+S21402E100F0DD2DE9004090E50050A0E30030D4E5B4\r
+S21402E1100180A0E1050053E104B04CE20070A0E1EA\r
+S21402E1200260A0E105A0A0E10310A0E12000000A21\r
+S21402E130FF3003E2200053E35000000AFF3011E2F2\r
+S21402E1401B00000A3B0053E30030A00301A0A0031B\r
+S21402E1500030C4051600000A0F0055E3054186D7B5\r
+S21402E160015085D2410000CA0010D4E5000051E3F8\r
+S21402E1700130A0E10B00000AFF3003E2200053E367\r
+S21402E1803600000A3B0053E30600000A220053E36F\r
+S21402E190014084121000000A0010D4E5000051E38A\r
+S21402E1A00130A0E1F3FFFF1AFF0011E30130A0E106\r
+S21402E1B0DEFFFF1A00005AE3013084120030871592\r
+S21402E1C000408705002096E5C0009FE5C0109FE549\r
+S21402E1D0005088E5F06D1BE9300000EA052186E074\r
+S21402E1E0043012E5040053E10140840204400205B3\r
+S21402E1F00010D405FF2011E20030A0030130A01366\r
+S21402E200220052E30030A00301300312000053E361\r
+S21402E2100420A0E10130A0E10800000AFF3003E27A\r
+S21402E2205C0053E30110F4050110C2E40110F4E5AA\r
+S21402E230000051E3220051130130A0E1F6FFFF1A5D\r
+S21402E240FF0011E30200001A48009FE53AF8FFEBD0\r
+S21402E250D0FFFFEA040052E10030A0130030C215DE\r
+S21402E2600030A0E30030C4E50110F4E5CDFFFFEA7C\r
+S21402E27024009FE50410A0E12FF8FFEBB9FFFFEAA8\r
+S21402E2800110F4E5200051E3FCFFFF0AAAFFFFEAB3\r
+S21402E290A0320300F03303001C25030030250300E0\r
+S21402E2A00DC0A0E1F0DD2DE90050A0E104B04CE283\r
+S21402E2B00200A0E10170A0E10260A0E17C0200EB96\r
+S21402E2C0070055E10540A0E10080A0E10800000A31\r
+S21402E2D0001094E50600A0E10820A0E186FBFFEB13\r
+S21402E2E0000050E30400000A184084E2070054E1EC\r
+S21402E2F0F6FFFF1A0000A0E3F0AD1BE9000094E56C\r
+S21402E3006B0200EB080050E11700009A070055E187\r
+S21402E31001A0A0E31200000A050054E10820A0E1D3\r
+S21402E3200600A0E10B00000A001095E572FBFFEB69\r
+S21402E330000050E30030A0E10600001A00005AE395\r
+S21402E3400610A0E148009FE50D00001A001095E5B2\r
+S21402E35040009FE5F8F7FFEB185085E2070055E10D\r
+S21402E360ECFFFF1A00005AE30100000A0400A0E1D5\r
+S21402E370F0AD1BE920009FE5EFF7FFEB0A00A0E1F6\r
+S21402E380F0AD1BE9002094E503A0A0E1EAF7FFEB5D\r
+S21402E390EDFFFFEA582503007C25030080230300D7\r
+S21402E3A008C09DE50C0080E904209DE500309DE54F\r
+S21402E3B014C080E50010C0E50C3080E5102080E532\r
+S21402E3C00EF0A0E10DC0A0E1F0DF2DE904B04CE2B2\r
+S21402E3D010D04DE200A0A0E30CE09BE504909BE584\r
+S21402E3E001005EE300C0A01301C0A00308E09BE5A5\r
+S21402E3F030300BE500005EE300C0A00301C00C1243\r
+S21402E40000005CE30130A0E300A08E1509005AE18B\r
+S21402E4102C000BE50180A0E134300BE530401BE513\r
+S21402E4200F0000AA0AC0A0E10910A0E1103094E58E\r
+S21402E430000053E300C08315040094E5000050E397\r
+S21402E4400400001A083094E5000053E38500000A31\r
+S21402E450020053E38300000A011051E2184084E2EE\r
+S21402E460F1FFFF1A2CC01BE50250A0E10C0052E19E\r
+S21402E470140000AA051198E70030D1E52D0053E3F9\r
+S21402E4802B00000A08309BE5000053E32300000A35\r
+S21402E49000005AE31B00001A0CE09BE500005EE356\r
+S21402E4A00A00000A01005EE30531980708209B0572\r
+S21402E4B00030820501A0A0E32CC01BE5015085E2D6\r
+S21402E4C00C0055E1EAFFFFBA34001BE5F0AF1BE98A\r
+S21402E4D00C209BE5050198E708109BE50230A0E1B9\r
+S21402E4E0670000EB000050E30040A0E1F0FFFF1AD7\r
+S21402E4F0051198E778019FE510209BE58EF7FFEB64\r
+S21402E50034400BE5EAFFFFEA68019FE510109BE541\r
+S21402E51089F7FFEB00C0A0E334C00BE5DDFFFFEA9E\r
+S21402E52054019FE584F7FFEB08309BE534300BE59A\r
+S21402E530E0FFFFEA0060A0E3090056E10170D1E5C2\r
+S21402E54030401BE50610A0E1060000AA0030D4E524\r
+S21402E550011081E2070053E10900000A090051E1B7\r
+S21402E560184084E2F8FFFFBA000056E3D1FFFF1A14\r
+S21402E5700710A0E104019FE56FF7FFEB34600BE59F\r
+S21402E580CCFFFFEA103094E5000053E30200000AD5\r
+S21402E590003093E5000053E32C00001A043094E5A3\r
+S21402E5A0000053E31F00000A050198E7082094E5DF\r
+S21402E5B00230D0E53D0053E3053188100360800247\r
+S21402E5C00460931501508512000052E30700000A0A\r
+S21402E5D0010052E30C30940500608305102094E598\r
+S21402E5E00130A0E3003082E50160A0E3DDFFFFEA30\r
+S21402E5F00C1094E50600A0E10230A0E1200000EB3A\r
+S21402E600000050E338000BE5F3FFFF1A142094E5F0\r
+S21402E6100610A0E158009FE547F7FFEB38201BE500\r
+S21402E62034200BE5ECFFFFEA083094E5000053E3E4\r
+S21402E6300C2094050030920501308302E8FFFF0AA1\r
+S21402E640020053E3E7FFFF1A0C2094E5E3FFFFEA1C\r
+S21402E650141094E51C009FE537F7FFEB00E0A0E3FB\r
+S21402E66034E00BE5CCFFFFEA0C3094E5000083E5CE\r
+S21402E67078FFFFEA94250300BC250300DC2503008F\r
+S21402E68010260300F0452DE900C0D0E50180A0E188\r
+S21402E69020005CE30270A0E103A0A0E10140A0E339\r
+S21402E6A00A50A0E30060A0E34C00000AFF001CE34F\r
+S21402E6B00C30A0E12800000A000054E30200000A21\r
+S21402E6C0FF3003E2300053E33B00000AFFE00CE2B7\r
+S21402E6D030C04EE241104EE2FF200CE2FF3001E273\r
+S21402E6E0050053E3090052830040A0E3010080E2E4\r
+S21402E6F00420A0E10200009A61304EE2050053E3D6\r
+S21402E7000000008A0120A0E3000052E31700000A7E\r
+S21402E710FF300CE2090053E30020A0E30C20A09196\r
+S21402E7200600009A61304EE2050053E357204E92EF\r
+S21402E7300200009AFF3001E2050053E337204E92B2\r
+S21402E740050052E1090000AA0030D0E5952626E031\r
+S21402E750000053E303C0A0E1D6FFFF1A000057E310\r
+S21402E76000008715006088E50100A0E3F085BDE89B\r
+S21402E77000005AE30E00000A00C0DAE50A30A0E103\r
+S21402E780FF200CE2000052E30700000A0E0052E1EE\r
+S21402E7900500000A01C0F3E5FF200CE2000052E388\r
+S21402E7A00100000A0E0052E1F9FFFF1AFF001CE307\r
+S21402E7B0E9FFFF1A0000A0E3F085BDE80120D0E5DE\r
+S21402E7C0413042E2190053E320308292FF20039246\r
+S21402E7D0780052E302C0F0051050A003BAFFFFEA29\r
+S21402E7E001C0F0E520005CE3FCFFFF0AAEFFFFEA93\r
+S21402E7F00DC0A0E130D82DE90040A0E10150A0E113\r
+S21402E80004B04CE20410A0E164009FE523FAFFEB9B\r
+S21402E8100030A0E1000053E358309F050500A0E158\r
+S21402E8200020930550109FE5FF2F820203208202EC\r
+S21402E8300A00000A0410A0E140009FE517FAFFEB69\r
+S21402E8400030A0E1000053E30500A0E128109FE598\r
+S21402E8500000A01330A81B1918309FE5042093E58A\r
+S21402E860FF2FC2E30320C2E3A0F6FFEB0500A0E100\r
+S21402E87030A81BE9482603006084030054260300E0\r
+S21402E880582603000DC0A0E1F0DF2DE904B04CE2EB\r
+S21402E89028D04DE20070A0E14C100BE50280A0E10A\r
+S21402E8A0030100EB0010A0E3000050E30060A0E1CB\r
+S21402E8B00740A0E150100BE51900000A0020D7E53A\r
+S21402E8C0010052E11600000AFF3002E2250053E37F\r
+S21402E8D0014084E20010D4151300000A220053E31C\r
+S21402E8E0000058030B00001AFF2011E20030A003BC\r
+S21402E8F00130A013220052E30030A00301300312BD\r
+S21402E900000053E30300000A0110F4E5000051E39F\r
+S21402E91022005113FBFFFF1AFF0011E30120A0E1C2\r
+S21402E920E8FFFF1A50001BE5F0AF1BE90010D4E524\r
+S21402E9307B0051E3E8FFFF1A019084E20210F4E53F\r
+S21402E940000051E37D0051130300000A0110F4E5B4\r
+S21402E950000051E37D005113FBFFFF1AFF5011E246\r
+S21402E9605500000A0020A0E304A0A0E10900A0E1EF\r
+S21402E9700120C4E448104BE29CFFFFEB000050E38A\r
+S21402E9800050A0E14500000AC90000EB4C101BE550\r
+S21402E990003086E0010053E100A0A0E1380000AAA2\r
+S21402E9A00900A0E1C20000EB0A3060E00400A0E12A\r
+S21402E9B0026043E2BE0000EB010056E3000084E082\r
+S21402E9C0010040E21F0000DA011044E20020A0E34A\r
+S21402E9D0010050E10620C0E70400000A062080E09D\r
+S21402E9E0013050E4010050E1013042E5FAFFFF1A1F\r
+S21402E9F00020D5E5024049E2000052E30600000A84\r
+S21402EA00FF3002E2250053E30800000A0120C4E4B6\r
+S21402EA100120F5E5000052E3F8FFFF1A0700A0E127\r
+S21402EA20A30000EB0A1074E70060A0E1B9FFFFEA5A\r
+S21402EA300130D5E550101BE57B0053E30110A0031F\r
+S21402EA4050100BE5F0FFFFEA000056E3E7FFFFCAAF\r
+S21402EA50013044E2000053E10500000A061084E09B\r
+S21402EA600120D4E4013044E2000053E1012041E5F4\r
+S21402EA70F9FFFF1A062084E00030A0E3013042E5E9\r
+S21402EA80DAFFFFEA0910A0E144009FE52AF6FFEB51\r
+S21402EA900020A0E30000A0E30020C7E5F0AF1BE9DA\r
+S21402EAA00910A0E12C009FE523F6FFEB7C30A0E3E3\r
+S21402EAB00030CAE50010D4E596FFFFEA0910A0E18F\r
+S21402EAC014009FE51CF6FFEB0500A0E10050C7E529\r
+S21402EAD0F0AF1BE9642603007C260300942603009D\r
+S21402EAE00DC0A0E170D82DE904B04CE20060A0E1B0\r
+S21402EAF00150A0E10040A0E30420A0E10600A0E14E\r
+S21402EB000510A0E15EFFFFEB000050E3014084E247\r
+S21402EB1070A81B09F7FFFFEA030052E310402DE935\r
+S21402EB2002C0A0E10200009A013080E1030013E374\r
+S21402EB300F00000A01C04CE201007CE30800000A54\r
+S21402EB400020D0E50030D1E501C04CE2030052E1DE\r
+S21402EB50010080E2011081E20300001A01007CE35A\r
+S21402EB60F6FFFF1A0000A0E31080BDE8020063E093\r
+S21402EB701080BDE8040052E300E0A0E10140A0E1FD\r
+S21402EB801600009A00209EE5003094E5030052E14C\r
+S21402EB900D00000A01C04CE201007CE30E00A0E179\r
+S21402EBA00410A0E10800000A0020D0E50030D1E5FC\r
+S21402EBB001C04CE2030052E1010080E2011081E252\r
+S21402EBC0E9FFFF1A01007CE3F6FFFF1A04C04CE2DD\r
+S21402EBD004005CE304E08EE2044084E2E8FFFF8A7D\r
+S21402EBE001C04CE201007CE30E00A0E10410A0E1AB\r
+S21402EBF0DBFFFF0A0020D0E50030D1E501C04CE281\r
+S21402EC00030052E1010080E2011081E2D6FFFF1A02\r
+S21402EC1001007CE3F6FFFF1AD1FFFFEA003081E134\r
+S21402EC20030013E330402DE90020A0E10040A0E1FC\r
+S21402EC300500000A0130D1E4000053E30130C2E4CB\r
+S21402EC40FBFFFF1A0400A0E13080BDE858309FE5C4\r
+S21402EC5000E091E5000093E550209FE50E3060E06D\r
+S21402EC60005092E50E30C3E1050013E104C0A0E1B6\r
+S21402EC700700001A0E20A0E105E0A0E104208CE4C3\r
+S21402EC800420B1E5023060E00230C3E10E0013E179\r
+S21402EC90F9FFFF0A0C20A0E10130D1E4000053E3A3\r
+S21402ECA00130C2E4FBFFFF1AE5FFFFEAB0260300CD\r
+S21402ECB0B8260300030010E304E02DE500E0A0E11F\r
+S21402ECC00700000A0030D0E5000053E30200000A05\r
+S21402ECD00130F0E5000053E3FCFFFF1A00006EE08F\r
+S21402ECE004F09DE450309FE5001090E500C093E5E7\r
+S21402ECF048209FE501306CE0002092E50130C3E138\r
+S21402ED00020013E10500001A0210A0E10420B0E59B\r
+S21402ED1002306CE00230C3E1010013E1FAFFFF0AA1\r
+S21402ED200030D0E5000053E3EBFFFF0A0130F0E5C8\r
+S21402ED30000053E3FCFFFF1AE7FFFFEAB0260300DA\r
+S21402ED40B8260300000052E330402DE902C0A0E1DD\r
+S21402ED500200A0013080BD08013080E1030013E309\r
+S21402ED601F00000A01C042E201007CE31700000A0D\r
+S21402ED700020D0E50030D1E502E0A0E1020053E138\r
+S21402ED800300000AFF2002E2FF3003E2020063E013\r
+S21402ED903080BDE800005CE301C04CE20E00000AD1\r
+S21402EDA0FF001EE3010080E20B00000A01007CE384\r
+S21402EDB0011081E20500000A0020D0E50030D1E50E\r
+S21402EDC002E0A0E1020053E1F1FFFF0AECFFFFEAD6\r
+S21402EDD00020D0E50030D1E5E9FFFFEA0000A0E31D\r
+S21402EDE03080BDE8030052E300E0A0E10140A0E16C\r
+S21402EDF00300009A001090E5003094E5030051E10C\r
+S21402EE001700000A00005CE30E00A0E10410A0E177\r
+S21402EE1001C04CE20F00000A00E0DEE50030D4E557\r
+S21402EE200E0053E10E20A011D5FFFF1A00005CE38E\r
+S21402EE3001C04CE2E8FFFF0AFF001EE3E6FFFF0AFE\r
+S21402EE400120F0E50130F1E502E0A0E1020053E125\r
+S21402EE50F5FFFF0ACAFFFFEA0020DEE50030D4E530\r
+S21402EE60C7FFFFEA44509FE544009FE504C05CE20A\r
+S21402EE70D9FFFF0A003095E5002090E5013063E0F7\r
+S21402EE800130C3E1020013E1D3FFFF1A03005CE383\r
+S21402EE9004E08EE2044084E2D9FFFF9A00109EE569\r
+S21402EEA0003094E5030051E1EFFFFF0AD4FFFFEACA\r
+S21402EEB0B0260300B826030010402DE900E0A0E3C8\r
+S21402EEC001005EE1070000AA48409FE501C0A0E1FC\r
+S21402EED00130D0E401C05CE22E3C23E0032194E73B\r
+S21402EEE00EE422E0F9FFFF1A000051E30600000AD2\r
+S21402EEF020009FE52E3C21E0FF3003E2032190E74D\r
+S21402EF002114B0E10EE422E0F9FFFF1A0EE0E0E180\r
+S21402EF100E00A0E11080BDE8C02603000130A0E18B\r
+S21402EF200010A0E3030051E104E02DE50B0000AA67\r
+S21402EF3034E09FE503C0A0E10130D0E40118A0E16F\r
+S21402EF40213C23E08330A0E1BE2093E101C05CE2D5\r
+S21402EF50212422E00228A0E14218A0E1F5FFFF1AD0\r
+S21402EF600108A0E12008A0E104F09DE4C02A030005\r
+S21402EF7014C04DE200602CE90CD0A0E1FF1F2DE981\r
+S21402EF8000200FE140208DE500D081E500B090E53D\r
+S21402EF9000000FE1C00080E300F029E140009BE59D\r
+S21402EFA000F069E1FF7F9BE80EF0B0E1F07F80E8B9\r
+S21402EFB00000A0E30EF0A0E1F07F90E80100A0E1DF\r
+S21402EFC00EF0A0E1030040E2040050E300F19F9738\r
+S21402EFD0060000EAE8EF0200E8EF0200E8EF0200AF\r
+S21402EFE0F8EF0200F8EF02000A00A0E30EF0A0E13C\r
+S21402EFF00500A0E30EF0A0E10200A0E30EF0A0E1FF\r
+S21402F00008309FE5002093E5440092E50EF0A0E16B\r
+S21402F010E08103000DC0A0E110D82DE90F00A0E3A7\r
+S21402F02004B04CE2280000EB0040A0E11900A0E387\r
+S21402F030250000EB38309FE500C0A0E1002093E5F4\r
+S21402F0400000A0E3441092E5020051E310A81B1949\r
+S21402F05020001CE3B020D41118309F150020940520\r
+S21402F06014309F05030052E10000A0130100A00324\r
+S21402F07010A81BE9E081030018DF0000010018EF6A\r
+S21402F08004E02DE50010A0E10F00A0E304E09DE4FB\r
+S21402F0901D0000EA0F0050E30031A0E10800009ACC\r
+S21402F0A0803080E00331A0E1170050E3803043E275\r
+S21402F0B00300009A0031A0E1190050E3403083E2D9\r
+S21402F0C00030E0830300A0E10EF0A0E10DC0A0E155\r
+S21402F0D010D82DE904B04CE20040A0E1ECFFFFEBB3\r
+S21402F0E0104044E2010070E3070054130030E0E3EE\r
+S21402F0F010309F852001A0E1002093850031928781\r
+S21402F1000300A0E110A81BE9E83103000DC0A0E14E\r
+S21402F11030D82DE904B04CE20150A0E10040A0E155\r
+S21402F120DBFFFFEB104044E2010070E307005413DC\r
+S21402F1300C309F852011A0E1002093850151828723\r
+S21402F14030A81BE9E83103000DC0A0E130D82DE954\r
+S21402F15004B04CE20150A0E10040A0E1CCFFFFEB7E\r
+S21402F16000C0A0E101007CE3104044E20500A0E1FB\r
+S21402F1700800000A24309FE5070054E3001093E5D8\r
+S21402F1800C20A0930420A0830C1081E040F5FFEB36\r
+S21402F1900100A0E330A81BE90000A0E330A81BE9A9\r
+S21402F1A0E83103000DC0A0E130D82DE904B04CE2EE\r
+S21402F1B00150A0E10040A0E1B5FFFFEB010070E3C3\r
+S21402F1C000C0A0E1104044E20510A0E10800000AD9\r
+S21402F1D024309FE5070054E3000093E50C20A0933B\r
+S21402F1E00420A0830C0080E029F5FFEB0100A0E3D9\r
+S21402F1F030A81BE90000A0E330A81BE9E8310300B1\r
+S21402F200100F10EE2008A0E1FF0000E2040050E319\r
+S21402F2100000A0930100A0830EF0A0E10DC0A0E1C3\r
+S21402F22010D82DE90040A0E104B04CE21900A0E39A\r
+S21402F230A5FFFFEB243EA0E10020A0E30F0053E36E\r
+S21402F24003F19F97110000EA88F2020098F202008A\r
+S21402F250A4F20200ACF20200B4F20200BCF2020017\r
+S21402F260C8F20200D0F20200D8F20200ECF202006B\r
+S21402F270FCF202001CF302003CF3020060F3020000\r
+S21402F2807CF3020084F30200203FA0E1012003E2A7\r
+S21402F2900200A0E110A81BE9203FA0E1013023E212\r
+S21402F2A0F9FFFFEAA03EA0E1F7FFFFEAA03EA0E1D9\r
+S21402F2B0F9FFFFEAA02FA0E1F4FFFFEA0020E0E159\r
+S21402F2C0A22FA0E1F1FFFFEA203EA0E1EEFFFFEA57\r
+S21402F2D0203EA0E1F0FFFFEA063200E2020253E31C\r
+S21402F2E00020A0130120A003E8FFFFEA063200E296\r
+S21402F2F0022253E20120A013E4FFFFEA092200E201\r
+S21402F300000052E30030A0130130A003090252E3CA\r
+S21402F3100320A01101208303DCFFFFEA092200E29A\r
+S21402F320010252E30030A0130130A003020152E3AF\r
+S21402F3300320A01101208303D4FFFFEA202FA0E1BF\r
+S21402F340012022E2093200E2000053E309025313CD\r
+S21402F350012002E20020A01301200202CBFFFFEAF6\r
+S21402F360202FA0E1093200E2010253E30201531307\r
+S21402F370012002E201208203C4FFFFEA0120A0E38B\r
+S21402F380C2FFFFEA0E3404E20A0453E30020A0138D\r
+S21402F3900120A003BDFFFFEA0DC0A0E130D82DE991\r
+S21402F3A00040A0E104B04CE20F0000E246FFFFEB93\r
+S21402F3B0100014E33E3D04020050A0E1C303A00186\r
+S21402F3C01800001A603004E2C332A0E1030053E3DF\r
+S21402F3D003F19F97040000EAE8F30200F4F3020048\r
+S21402F3E0FCF3020004F402001550A0E10500A0E1BF\r
+S21402F3F030A81BE93550A0E1FBFFFFEA5550A0E11B\r
+S21402F400F9FFFFEA000050E37550A011F6FFFF1A5D\r
+S21402F4101900A0E32CFFFFEBA550A0E1020210E3C7\r
+S21402F42002518513F0FFFFEA0F0C04E24004A0E14C\r
+S21402F43025FFFFEBE2FFFFEA033301E20DC0A0E186\r
+S21402F440233DA0E1F0D82DE904B04CE20150A0E142\r
+S21402F4500040A0E1030053E303F19F97620000EA35\r
+S21402F46070F40200F4F502009CF6020048F702006F\r
+S21402F4700F32C1E3F0229FE52F30C3E3020053E1CF\r
+S21402F4805600000A0F3A01E20F0A53E3046080E2D4\r
+S21402F4900100000A0600A0E1F0A81BE9CC329FE5B5\r
+S21402F4A0CC229FE5033001E0020053E1F8FFFF0A99\r
+S21402F4B00F4801E22408A0E103FFFFEB0F0854E324\r
+S21402F4C00070A0E108708002020415E30F3C0512EA\r
+S21402F4D0A333A011FF4005127443A0113A00000A9C\r
+S21402F4E01E3605E2A33AA0E10F0053E303F19F970D\r
+S21402F4F0E7FFFFEA34F502003CF5020044F502009D\r
+S21402F5004CF5020054F502005CF5020078F50200A4\r
+S21402F51098F5020094F4020094F4020094F40200B7\r
+S21402F52094F40200ACF50200B4F50200BCF5020049\r
+S21402F530C4F50200046007E0D5FFFFEA046027E096\r
+S21402F540D3FFFFEA076064E0D1FFFFEA046067E0EA\r
+S21402F550CFFFFFEA046087E0CDFFFFEA1900A0E3D1\r
+S21402F560D9FEFFEBA00EA0E1043087E0010000E226\r
+S21402F570006083E0C6FFFFEA1900A0E3D2FEFFEBBD\r
+S21402F580073064E0A00EA0E1010000E2003083E054\r
+S21402F590016043E2BEFFFFEA1900A0E3CAFEFFEBEA\r
+S21402F5A0043067E0A00EA0E1F6FFFFEA046087E100\r
+S21402F5B0B7FFFFEA0460A0E1B5FFFFEA0460C7E117\r
+S21402F5C0B3FFFFEA0460E0E1B1FFFFEA050AA0E14B\r
+S21402F5D0200AA0E16FFFFFEB0040A0E1BFFFFFEAB9\r
+S21402F5E00F0001E2F0681BE9B7FEFFEA0000A0E3A5\r
+S21402F5F0F0A81BE97C219FE5023001E0020053E1FE\r
+S21402F6000400000A010611E30200000A0F3A01E2B2\r
+S21402F6100F0A53E30100000A040084E2F0A81BE983\r
+S21402F6200F4801E22408A0E1A7FEFFEB0F0854E30F\r
+S21402F6300070A0E108708002010415E30800000AC9\r
+S21402F640020415E30800001A020515E3053AA011A4\r
+S21402F650053AA001233AA011233AA00103708710AD\r
+S21402F66007706300000097E5F0A81BE9020515E3A2\r
+S21402F6700400000A050AA0E1200AA0E145FFFFEB0C\r
+S21402F680007087E0F6FFFFEA050AA0E1200AA0E183\r
+S21402F69040FFFFEB077060E0F1FFFFEA026411E251\r
+S21402F6A01700001A010611E3DAFFFF0A020911E346\r
+S21402F6B0D8FFFF0A0F4801E22408A0E182FEFFEB12\r
+S21402F6C00F0854E30070A0E1087080020508A0E16C\r
+S21402F6D00620A0E12008A0E10630A0E10110A0E388\r
+S21402F6E011C310E0013083E2012082120E0053E3C0\r
+S21402F6F0FAFFFFDA020515E302718710047047026B\r
+S21402F700D7FFFFEA0100A0E1C3FEFFEB000050E3D3\r
+S21402F710C0FFFF0AFF34C5E30301A0E1020515E3BB\r
+S21402F7203F038013FE3405E2002084E0FA0453E32C\r
+S21402F730086082E256FFFF1A010415E30260861390\r
+S21402F740016086E352FFFFEA033401E2030453E357\r
+S21402F750B0FFFF1A0100A0E1AFFEFFEB000050E38E\r
+S21402F7600800A013F0A81B19AAFFFFEA10FF2F013A\r
+S21402F7700000BF0F00000F01100000020118A0E1F8\r
+S21402F780213EA0E10DC0A0E1022080E2043043E267\r
+S21402F79070D82DE904B04CE20060A0E1015082E38B\r
+S21402F7A04148A0E10B0053E303F19F970F0000EAE4\r
+S21402F7B0E0F70200F0F70200F0F70200F0F70200AE\r
+S21402F7C0F0F70200F0F70200F0F702000CF8020071\r
+S21402F7D0F0F7020064F80200A8F80200CCF8020073\r
+S21402F7E038319FE5033004E0470C53E30100000A7A\r
+S21402F7F00500A0E170A81BE9780004E2A001A0E1E0\r
+S21402F80031FEFFEB0050A0E1F8FFFFEA0F3C04E2F6\r
+S21402F8100D0C53E3F5FFFF1A0D00A0E32AFEFFEBE3\r
+S21402F8200438A0E10020A0E10000A0E32318A0E134\r
+S21402F83000C0A0E1513CA0E1010013E301C08CE24C\r
+S21402F8400400801207005CE3F9FFFFDA005092E73B\r
+S21402F8506AFEFFEB000050E3E4FFFF1A015085E367\r
+S21402F860E2FFFFEA0F3C04E2030AA0E10F0250E3C4\r
+S21402F8700850A003DDFFFF0A67FEFFEB000050E31F\r
+S21402F880DAFFFF0AFF3004E2800014E38300A0E1FF\r
+S21402F890800BE011A00BE011003086E0043083E21A\r
+S21402F8A0015083E3D1FFFFEA020B14E3CFFFFF1AF6\r
+S21402F8B0843AA0E1A33AA0E1010B14E38300A0E19D\r
+S21402F8C0800AE011A00AE011F2FFFFEA020B14E33D\r
+S21402F8D0C6FFFF1A843AA0E1010B14E3A33AA0E1A3\r
+S21402F8E0F240D6E10306A0E18004E0113A3B04E2CE\r
+S21402F8F0A004E0113A0B53E3BCFFFF1A843AA0E1DE\r
+S21402F900A33AA0E1830080E1002086E0010A14E326\r
+S21402F910045082E20350C503B4FFFF0ACEFFFFEA9B\r
+S21402F92007FF00000DC0A0E170D82DE90F00A0E38C\r
+S21402F93004B04CE2E4FDFFEB0050A0E11900A0E3A6\r
+S21402F940E1FDFFEB0030A0E1200013E30500A0E19B\r
+S21402F95078609FE51000000AB010D5E186FFFFEB45\r
+S21402F960000086E5000096E5010010E30110C0E302\r
+S21402F970B020D11158309F1500309005B020C31129\r
+S21402F98050209F0550209F1550109F05003082057D\r
+S21402F990B020C1110010800570A81BE9004095E553\r
+S21402F9A028609FE50400A0E11BFEFFEB0030A0E10B\r
+S21402F9B00410A0E1000053E3044085E20500A0E144\r
+S21402F9C000408605E6FFFF0A9AFEFFEBE3FFFFEA2A\r
+S21402F9D0183203008C6F0300886F0300BEBEFFFF61\r
+S21402F9E0FEDEFFE738309FE5001093E5000051E3A6\r
+S21402F9F00EF0A001010011E328309F1528309F0564\r
+S21402FA00B030D3110120C1E300209305B030C211FB\r
+S21402FA100C309FE5002081050020A0E3002083E54E\r
+S21402FA200EF0A0E1183203008C6F0300886F03000B\r
+S21402FA300EF0A0E10EF0A0E10DC0A0E100D82DE985\r
+S21402FA400F00A0E304B04CE29FFDFFEB0C309FE5F5\r
+S21402FA50030050E10000A0130100A00300A81BE968\r
+S21402FA60B08E02000DC0A0E110D82DE90F00A0E371\r
+S21402FA7004B04CE294FDFFEB0040A0E11900A0E3C5\r
+S21402FA8091FDFFEB200010E3024084120440840242\r
+S21402FA900410A0E10F00A0E310681BE99AFDFFEA3C\r
+S21402FAA00DC0A0E100D82DE964109FE50020A0E378\r
+S21402FAB0003091E504B04CE2000053E354309FE579\r
+S21402FAC0002083E500A81B19010010E30A00000AC3\r
+S21402FAD0000081E50100C0E3B030D0E1B430C1E1FE\r
+S21402FAE034309FE5B030C0E10300A0E329ECFFEB21\r
+S21402FAF00300A0E300681BE924ECFFEA000081E5AE\r
+S21402FB00002090E514309FE5042081E5003080E572\r
+S21402FB10F4FFFFEA906F03001C320300BEBEFFFF35\r
+S21402FB20FEDEFFE70DC0A0E100D82DE968309FE5B4\r
+S21402FB300010A0E3003093E504B04CE2010053E16C\r
+S21402FB4058C09FE50400001A00209CE50310A0E1BF\r
+S21402FB500130C2E3030050E10100000A0100A0E107\r
+S21402FB6000A81BE9010012E304309C05B4C0DC11B6\r
+S21402FB700030800524309FE50020A0E3B0C0C0110D\r
+S21402FB80002083E50300A0E302ECFFEB0300A0E302\r
+S21402FB90FEEBFFEB0110A0E3EFFFFFEA1C320300CF\r
+S21402FBA0906F03000DC0A0E130D82DE97C509FE590\r
+S21402FBB07C309FE5001095E50020A0E3000051E3AD\r
+S21402FBC00040A0E104B04CE2002083E50100A0E181\r
+S21402FBD00300000AD2FFFFEB001095E5000051E398\r
+S21402FBE030A81B191900A0E337FDFFEB013084E3B0\r
+S21402FBF0200010E300308515B030D4110040850592\r
+S21402FC00B430C5110020940528309F1528309F0572\r
+S21402FC1004208505B030C411003084050300A0E33B\r
+S21402FC20DCEBFFEB0300A0E330681BE9D7EBFFEA4F\r
+S21402FC30906F03001C320300BEBEFFFFFEDEFFE72E\r
+S21402FC400C309FE5000093E5000050E20100A0138F\r
+S21402FC500EF0A0E1906F03000DC0A0E1F0D92DE9EF\r
+S21402FC600000A0E304B04CE214D04DE216FDFFEB18\r
+S21402FC700040A0E10100A0E313FDFFEB0070A0E14D\r
+S21402FC800200A0E310FDFFEB0060A0E10300A0E38A\r
+S21402FC900DFDFFEB0050A0E10D00A0E30AFDFFEB17\r
+S21402FCA00030A0E11900A0E3048093E506FDFFEB17\r
+S21402FCB00030A0E11F3003E2130053E30C00A0E380\r
+S21402FCC00E00A01300FDFFEB0010A0E10F00A0E362\r
+S21402FCD00DFDFFEBFA0F54E30710A0E10620A0E1AA\r
+S21402FCE00530A0E10400A0E102C0A0E30900000A7A\r
+S21402FCF024C04BE228404BE200118DE808408DE517\r
+S21402FD00350200EB0030A0E10000A0E3000053E162\r
+S21402FD1005C0A0030100001A0C00A0E1F0A91BE92F\r
+S21402FD2024101BE5F8FCFFEB28C01BE5F9FFFFEAF1\r
+S21402FD30001090E50030A0E3303081E51A20A0E301\r
+S21402FD40033083E2242081E5283081E50C309FE5EC\r
+S21402FD50562082E22C2081E5303081E50EF0A0E1CB\r
+S21402FD6001030000000090E5FF1001E2183090E564\r
+S21402FD70200013E3FCFFFF1A0A0051E3001080E59F\r
+S21402FD800EF0A011183090E5200013E30D30A0030A\r
+S21402FD90003080050EF0A001F9FFFFEA003090E582\r
+S21402FDA06400A0E3010050E2182093E50EF0A001E3\r
+S21402FDB0100012E3FAFFFF1A003093E50100A0E3F9\r
+S21402FDC00030C1E50EF0A0E10DC0A0E130D82DE96B\r
+S21402FDD004B04CE204D04DE20040A0E115504BE2E4\r
+S21402FDE00400A0E10510A0E1EBFFFFEB000050E3EA\r
+S21402FDF015005B1530A81B19F8FFFFEA0DC0A0E13D\r
+S21402FE00000052E370D82DE904B04CE20060A0E195\r
+S21402FE100150A0E1014042E270A81B090110D5E49E\r
+S21402FE200600A0E1FF1001E2CDFFFFEB000054E365\r
+S21402FE30014044E270A81B09F7FFFFEA0DC0A0E1EB\r
+S21402FE40000052E370D82DE904B04CE20060A0E155\r
+S21402FE500150A0E1014042E270A81B090600A0E1A1\r
+S21402FE60D8FFFFEB000054E30100C5E4014044E282\r
+S21402FE7070A81B09F8FFFFEA0DC0A0E1F0D82DE933\r
+S21402FE80043090E550709FE5033183E004B04CE205\r
+S21402FE900060A0E10150A0E18340A0E10510A0E1CE\r
+S21402FEA00600A0E1BCFFFFEB0030A0E1000053E338\r
+S21402FEB06400A0E3014044E20500001A010074E376\r
+S21402FEC00300000A483097E50FE0A0E103F0A0E146\r
+S21402FED0F1FFFFEA0300A0E1F0A81BE950000000D2\r
+S21402FEE00DC0A0E10E002DE910D82DE910B04CE2AD\r
+S21402FEF004309BE50040A0E3043043E2030053E3F2\r
+S21402FF0003F19F970B0000EA40FF020018FF020071\r
+S21402FF1064FF02006CFF0200001090E558309FE577\r
+S21402FF2050C0A0E30120A0E3002083E538C081E5AD\r
+S21402FF30080090E54DE4FFEB0400A0E110A81BE9E1\r
+S21402FF4034209FE5001090E50030A0E3004092E5E3\r
+S21402FF50003082E5383081E5080090E538E4FFEBB2\r
+S21402FF60F4FFFFEA084090E5F2FFFFEA08309BE55F\r
+S21402FF70044090E5043080E5EEFFFFEA38320300E5\r
+S21402FF800DC0A0E1F0D82DE904B04CE204D04DE259\r
+S21402FF900040A0E1080090E50170A0E10160A0E346\r
+S21402FFA0990000EB4231A0E3006083E5004094E54F\r
+S21402FFB00050A0E3005087E5183094E51C004BE2A1\r
+S21402FFC0100013E30610A0E10100000A0500A0E1FC\r
+S21402FFD0F0A81BE9003094E50650A0E1013060E588\r
+S21402FFE04AEDFFEB000050E300608715F6FFFFEADC\r
+S21402FFF00DC0A0E1F0DF2DE9E0509FE504B04CE231\r
+S21403000004D04DE20000E0E3343095E50FE0A0E1D4\r
+S21403001003F0A0E1C8409FE52C000BE5080094E53B\r
+S21403002007E4FFEB140094E505E4FFEB0400A0E10E\r
+S2140300303EFFFFEBAC009FE53CFFFFEB343095E55E\r
+S2140300400000A0E30FE0A0E103F0A0E1143095E583\r
+S21403005094209FE5004083E590609FE5042083E5B8\r
+S2140300608C709FE58C809FE58CA09FE58C909FE528\r
+S2140300708C209FE50100A0E3082083E50C6083E560\r
+S214030080107083E5148083E518A083E51C9083E550\r
+S214030090342095E50FE0A0E102F0A0E1143095E5E9\r
+S2140300A040209FE52C001BE5002083E538209FE5D4\r
+S2140300B0042083E548209FE5082083E50C6083E55C\r
+S2140300C0107083E5148083E518A083E51C9083E510\r
+S2140300D0342095E50FE0A0E102F0A0E1F0AF1BE9C4\r
+S2140300E050000000203203002C320300FCFD020007\r
+S2140300F064FD0200C8FD0200E0FE020080FF02006D\r
+S21403010078FE02003CFE020004E02DE518209FE581\r
+S214030110003092E5000053E304F09D140130A0E3A1\r
+S214030120003082E504E09DE4B0FFFFEA3C320300C2\r
+S21403013004E02DE50CC09DE500E0A0E308308CE567\r
+S21403014004309DE500008CE50C308CE508309DE519\r
+S21403015004108CE510208CE514E08CE518E08CE5A3\r
+S21403016000C083E504F09DE40DC0A0E110D82DE99E\r
+S2140301700040A0E1041094E5000090E504B04CE2D2\r
+S214030180C6E3FFEB001094E534009FE534309FE5AB\r
+S214030190012190E7030052E110A81B19083094E5EB\r
+S2140301A0013180E7000094E5102094E518309FE5C0\r
+S2140301B0002183E7001094E510309FE5014183E7B3\r
+S2140301C010A81BE9C42D030098B50200C82E03002F\r
+S2140301D0CC2F03000DC0A0E130D82DE904B04CE2CB\r
+S2140301E000500FE100400FE1C04084E304F029E132\r
+S2140301F09EE3FFEB00300FE1C04005E2C030C3E3EF\r
+S214030200043083E103F029E130A81BE904E02DE57F\r
+S21403021004E09DE4A0E3FFEA0EF0A0E10DC0A0E138\r
+S21403022070D82DE904B04CE268C09FE50040A0E317\r
+S2140302300130A0E360009CE85C209FE5035095E056\r
+S214030240001092E50460A6E01C00A0E360008CE8C2\r
+S21403025030E3FFEB1C00A0E3EBFFFFEB3C309FE536\r
+S2140302600010A0E3002093E5010052E10700000A16\r
+S2140302702C309FE50100A0E1003093E5010053E137\r
+S214030280341093153C0093150FE0A0E102F0A0E1B3\r
+S2140302900100A0E370A81BE9883203009032030034\r
+S2140302A094320300E08203000DC0A0E110D82DE9CC\r
+S2140302B048309FE50CD04DE204B04CE240409FE549\r
+S2140302C0000093E501E3FFEB0010A0E334C09FE5D5\r
+S2140302D034E09FE534309FE50120A0E11C00A0E355\r
+S2140302E000C08DE510408DE990FFFFEB000094E51C\r
+S2140302F09CFFFFEB1C00A0E310681BE9B4FFFFEABA\r
+S21403030090320300986F0300180203009C6F0300EB\r
+S2140303101C0203000DC0A0E1F0D82DE90040A0E3C5\r
+S214030320020054E104B04CE20250A0E10160A0E1F7\r
+S214030330120000AA4C709FE5143097E5000053E3C3\r
+S21403034018309705000093E5103093E50FE0A0E121\r
+S21403035003F0A0E1FF0000E20D0050E30A00501393\r
+S214030360042086000030A0030400C6E70130C2055F\r
+S2140303700200000A014084E2050054E1EDFFFFBAE3\r
+S2140303800400A0E1F0A81BE9500000000DC0A0E1A6\r
+S214030390000052E370D82DE904B04CE20260A0E1FD\r
+S2140303A00140A0E10250A0E1130000DA0010D4E5FA\r
+S2140303B09C009FE50A0051E30D20A0E31900000A04\r
+S2140303C08C009FE5FF2001E2143090E50210A0E1C7\r
+S2140303D0000053E3183090050210A001000093E5D7\r
+S2140303E0015045E20C3093E50FE0A0E103F0A0E1F5\r
+S2140303F0000055E3014084E2EBFFFFCA50209FE56F\r
+S2140304000810A0E3143092E5000053E31830920579\r
+S214030410000093E5143093E50FE0A0E103F0A0E1BC\r
+S2140304200600A0E170A81BE9143090E50210A0E1D5\r
+S214030430000053E3183090050210A001000093E576\r
+S2140304400C3093E50FE0A0E103F0A0E10010D4E543\r
+S214030450DAFFFFEA500000000400E0E30EF0A0E13C\r
+S2140304600000A0E30EF0A0E10400E0E30EF0A0E13C\r
+S2140304700DC0A0E170D82DE96C209FE504B04CE2D6\r
+S214030480003092E50060A0E1000053E31200000A8A\r
+S214030490000056E30E00000A50309FE550C09FE56B\r
+S2140304A0030093E800209CE501E2A0E1205E8EE1D4\r
+S2140304B00042A0E1004054E00150C5E005C1A0E1C0\r
+S2140304C00030A0E3241F8CE10401A0E1E70000EB69\r
+S2140304D0000086E50000A0E370A81BE90130A0E356\r
+S2140304E0003082E56FFFFFEBE8FFFFEA9C32030074\r
+S2140304F0883203009832030004E02DE51C209FE5B4\r
+S214030500000051E314209F0500309215000082E599\r
+S2140305100000A0E30030811504E09DE4D3FFFFEA6A\r
+S214030520943203000DC0A0E1F0DF2DE90060A0E1E6\r
+S21403053004B04CE20000A0E30170A0E1CBFFFFEBA8\r
+S214030540020076E3FA6FA0031700000A000056E3E2\r
+S2140305500030A0D30130A0C358309F05FA6FA0E344\r
+S214030560006093051000000A000053E348A09FE5CF\r
+S2140305700090A0E3FA8FA0E338C09FE50A00000AC4\r
+S21403058030009AE834009FE534109FE500209CE590\r
+S214030590000081E5940881E00030A0E3951821E08F\r
+S2140305A000608CE5B10000EB03008AE8000057E327\r
+S2140305B000608715F0AF1BE998320300883203000A\r
+S2140305C0C05D00009032030008309FE50020A0E3E2\r
+S2140305D0002083E50EF0A0E1943203000DC0A0E1F5\r
+S2140305E030D82DE904B04CE20CC09BE50040A0E3F4\r
+S2140305F0110050E302E0A0E10150A0E10320A0E1D6\r
+S21403060000408CE55A00000A3C00008A050050E3CF\r
+S2140306103600000A2300008A020050E31D00000A89\r
+S2140306201000008A010050E30100000A0000A0E366\r
+S21403063030A81BE90030E0E3B4219FE500308CE5E9\r
+S214030640003092E50140A0E1000053E30530A0131B\r
+S2140306500040A01100308C1508309BE50100A0E394\r
+S214030660004083E530A81BE9030050E30600000AB8\r
+S214030670040050E3ECFFFF1A0100A0E10E10A0E116\r
+S21403068023FFFFEB0040A0E1F2FFFFEA0100A0E139\r
+S21403069072FFFFEBFAFFFFEA0100A0E10E10A0E1F4\r
+S2140306A06CFFFFEBF6FFFFEA070050E30400000AC7\r
+S2140306B00A00003A0A0050E30300000A0F0050E362\r
+S2140306C0D9FFFF1A5740E0E3E2FFFFEA013AA0E34F\r
+S2140306D0022AA0E32C308EE504208EE5DDFFFFEA38\r
+S2140306E00100A0E10E10A0E15EFFFFEBE4FFFFEACE\r
+S2140306F00100A0E10E10A0E123FFFFEBE0FFFFEAFD\r
+S214030700F0309FE5030050E13500000A1B00008A25\r
+S214030710140050E31600000A0200008A130050E398\r
+S214030720CCFFFF0AC0FFFFEACC309FE5030050E191\r
+S2140307300600000AFA3F83E2030050E1BAFFFF1AFD\r
+S2140307400100A0E10E10A0E16AFFFFEBC1FFFFEA84\r
+S214030750A8309FE5A8209FE5001093E5003092E5BA\r
+S2140307600140A0E3013063E0003085E500108EE52C\r
+S214030770B8FFFFEA0500A0E13CFFFFEBC0FFFFEA7E\r
+S21403078080309FE5030050E11300000A0700008A4B\r
+S21403079074309FE5030050E10200000A6C309FE5C9\r
+S2140307A0030050E1C5FFFFEA86FFFFEBA9FFFFEA60\r
+S2140307B05C309FE5030050E10500000A54309FE5D6\r
+S2140307C0030050E198FFFF1A4C309FE5003081E5A7\r
+S2140307D0A0FFFFEA0040E0E39EFFFFEA0140A0E33C\r
+S2140307E09CFFFFEA0100A0E10E10A0E14CFFFFEB27\r
+S2140307F098FFFFEAC0840300D2070000E903000065\r
+S2140308004083030000840300BA0B0000D3070000F4\r
+S214030810B90B0000BB0B0000ADBA0000403203006A\r
+S214030820000052E370402DE920C062E20140A0E1DF\r
+S2140308300030A0E10060A0E30050A0E30800000A37\r
+S21403084000005CE33032A0E100E06CE2C16FA0D1AF\r
+S214030850515EA0D15162A0C1115C83C10640A0E1E4\r
+S2140308600530A0E10410A0E10300A0E17080BDE81C\r
+S2140308700DC0A0E100D82DE904B04CE204D04DE24F\r
+S21403088000C0A0E300C08DE5000000EB00A81BE954\r
+S2140308900DC0A0E1F0DF2DE904B04CE20060A0E358\r
+S2140308A00050A0E330C04BE230D04DE2004053E2AC\r
+S2140308B00090A0E160008CE860000CE90260A0E113\r
+S2140308C00150A0E1D700001A010052E15400009A3B\r
+S2140308D0010852E30210A0E14D00002AFF0052E394\r
+S2140308E00800A0830000A093A8259FE53110A0E18F\r
+S2140308F00130D2E7003083E0203073E240300BE56E\r
+S2140309000500000A40201BE5203063E23933A0E1EE\r
+S214030910155283E11662A0E11992A0E12678A0E1C0\r
+S2140309200710A0E10500A0E10E0300EB0710A0E10D\r
+S2140309300040A0E10500A0E1E40200EB06A8A0E168\r
+S2140309402AA8A0E19A0002E02938A0E1044883E13E\r
+S214030950020054E10080A0E10500002A064094E06E\r
+S214030960018040E20200002A020054E1018048327E\r
+S21403097006408430044062E00710A0E10400A0E1D2\r
+S214030980F80200EB0710A0E10050A0E10400A0E18C\r
+S214030990CE0200EB9A0002E00938A0E12338A0E17A\r
+S2140309A0055883E1020055E10500002A065095E04C\r
+S2140309B0010040E20200002A020055E1065085309D\r
+S2140309C00100403208C880E1059062E000A0A0E381\r
+S2140309D004309BE5000053E30800000A40401BE593\r
+S2140309E00050A0E33994A0E138900BE534500BE5B2\r
+S2140309F030204BE20C0012E904409BE50C0084E82F\r
+S214030A0030C00BE52CA00BE530604BE2030096E804\r
+S214030A10F0AF1BE9010452E31800A0231000A03333\r
+S214030A20B0FFFFEA000052E30300001A0210A0E141\r
+S214030A300100A0E3A50200EB0060A0E1010856E375\r
+S214030A407400002AFF0056E30800A0830000A0936A\r
+S214030A5040249FE53610A0E10130D2E7003083E062\r
+S214030A60203073E240300BE50550660001A0A0037A\r
+S214030A702688A0013800000A40401BE540301BE5ED\r
+S214030A801664A0E1203063E235A3A0E12688A0E146\r
+S214030A9006C8A0E12CC8A0E13C300BE50A00A0E1A3\r
+S214030AA03933A0E10810A0E1155483E148C00BE5F3\r
+S214030AB0AC0200EB0810A0E10070A0E10A00A0E180\r
+S214030AC0820200EB48201BE52538A0E1900202E0F5\r
+S214030AD0077883E1020057E100A0A0E11994A0E1A2\r
+S214030AE044800BE50500002A067097E001A040E26B\r
+S214030AF00200002A020057E101A04A32067087303E\r
+S214030B00077062E044101BE50700A0E1950200EBC6\r
+S214030B1044101BE50040A0E10700A0E16B0200EBD8\r
+S214030B2048201BE50538A0E1900202E02338A0E147\r
+S214030B30044883E1020054E10500002A064094E0DD\r
+S214030B40010040E20200002A020054E101004032A4\r
+S214030B50064084300AA880E1045062E00628A0E13B\r
+S214030B602228A0E10810A0E10500A0E14C200BE537\r
+S214030B707C0200EB0810A0E10040A0E10500A0E124\r
+S214030B80520200EB4C201BE52938A0E1900202E05C\r
+S214030B90044883E1020054E10070A0E10500002A46\r
+S214030BA0064094E0017040E20200002A020054E18D\r
+S214030BB00170473206408430044062E00810A0E12A\r
+S214030BC00400A0E1670200EB0810A0E10050A0E1DA\r
+S214030BD00400A0E13D0200EB4C201BE50938A0E130\r
+S214030BE0900202E02338A0E1055883E1020055E1B4\r
+S214030BF00500002A065095E0010040E20200002AA4\r
+S214030C00020055E1065085300100403207C880E1F6\r
+S214030C10059062E06DFFFFEA010456E31800A02387\r
+S214030C201000A03389FFFFEA010054E10A00009A8E\r
+S214030C3004309BE500A0A0E3000053E30AC0A0E154\r
+S214030C406EFFFF0A38000BE534100BE530404BE22D\r
+S214030C50300014E9300083E868FFFFEA010854E334\r
+S214030C608800002AFF0054E30800A0830000A09336\r
+S214030C7020229FE53410A0E10130D2E7003083E064\r
+S214030C80203073E240300BE51200001A040055E1F1\r
+S214030C900600599140C01B350300003A06C059E0D0\r
+S214030CA00450C5E00C90A0E101C0A0E304209BE53E\r
+S214030CB000A0A0E3000052E350FFFF0A34500BE508\r
+S214030CC038900BE530304BE2180013E90250A0E1F0\r
+S214030CD0180082E849FFFFEA40C01BE540201BE5F9\r
+S214030CE020C06CE2363CA0E1144283E12438A0E144\r
+S214030CF035ACA0E150300BE53CC00BE5393CA0E138\r
+S214030D0004C8A0E12CC8A0E10A00A0E150101BE52E\r
+S214030D10155283E154C00BE5120200EB50101BE59D\r
+S214030D200080A0E10A00A0E1E80100EB54201BE5E7\r
+S214030D3000A0A0E1920A0AE02538A0E1088883E132\r
+S214030D4040301BE50A0058E158000BE51663A0E1A6\r
+S214030D501993A0E10700002A01C040E2048098E04E\r
+S214030D6058C00BE50300002A0A0058E101C04C32C4\r
+S214030D7058C00B350480883008806AE050101BE5A5\r
+S214030D800800A0E1F70100EB50101BE50070A0E19E\r
+S214030D900800A0E1CD0100EB54A01BE50538A0E157\r
+S214030DA0900A0AE02338A0E1077883E10A0057E1B6\r
+S214030DB00500002A047097E0010040E20200002AC2\r
+S214030DC00A0057E1010040320470873058201BE5C3\r
+S214030DD007706AE002C880E12C18A0E12608A0E1AB\r
+S214030DE00128CCE10038C6E192030EE0910303E04C\r
+S214030DF0900202E0910000E0022093E001088022C6\r
+S214030E0002E89EE02208A0E0070050E10600008A00\r
+S214030E100030A0130130A00309005EE10030A09368\r
+S214030E2001300382000053E30300000A06305EE04D\r
+S214030E300400C0E003E0A0E101C04CE204409BE5EF\r
+S214030E4000A0A0E3000054E3ECFEFF0A40201BE5ED\r
+S214030E500E6059E00050C7E03C401BE53632A0E187\r
+S214030E60153483E13552A0E134500BE538300BE5F9\r
+S214030E7030504BE20690A0E104209BE5600015E9A4\r
+S214030E80600082E8DDFEFFEA010454E31800A023B5\r
+S214030E901000A03375FFFFEAC02C03000DC0A0E1CD\r
+S214030EA000D82DE904B04CE20CD04DE214C04BE25E\r
+S214030EB000C08DE5020000EB10304BE2030013E8A0\r
+S214030EC000A81BE90DC0A0E1F0DF2DE904B04CE259\r
+S214030ED00060A0E30050A0E330C04BE230D04DE208\r
+S214030EE0004053E20090A0E160008CE860000CE94B\r
+S214030EF00260A0E10150A0E1D700001A010052E110\r
+S214030F005400009A010852E30210A0E14D00002AA3\r
+S214030F10FF0052E30800A0830000A093A8259FE5E6\r
+S214030F203110A0E10130D2E7003083E0203073E2D5\r
+S214030F3040300BE50500000A40201BE5203063E245\r
+S214030F403933A0E1155283E11662A0E11992A0E1BC\r
+S214030F502678A0E10710A0E10500A0E1810100EBDF\r
+S214030F600710A0E10040A0E10500A0E1570100EB57\r
+S214030F7006A8A0E12AA8A0E19A0002E02938A0E189\r
+S214030F80044883E1020054E10080A0E10500002A42\r
+S214030F90064094E0018040E20200002A020054E189\r
+S214030FA00180483206408430044062E00710A0E126\r
+S214030FB00400A0E16B0100EB0710A0E10050A0E1E4\r
+S214030FC00400A0E1410100EB9A0002E00938A0E129\r
+S214030FD02338A0E1055883E1020055E10500002A05\r
+S214030FE0065095E0010040E20200002A020055E1A7\r
+S214030FF0065085300100403208C880E1059062E063\r
+S21403100000A0A0E304309BE5000053E30800000AB9\r
+S21403101040401BE50050A0E33994A0E138900BE56F\r
+S21403102034500BE530204BE20C0012E904409BE5FC\r
+S2140310300C0084E830C00BE52CA00BE530604BE2D7\r
+S214031040030096E8F0AF1BE9010452E31800A0235F\r
+S2140310501000A033B0FFFFEA000052E30300001ABB\r
+S2140310600210A0E10100A0E3180100EB0060A0E17C\r
+S214031070010856E37400002AFF0056E30800A08325\r
+S2140310800000A09340249FE53610A0E10130D2E78C\r
+S214031090003083E0203073E240300BE505506600F5\r
+S2140310A001A0A0032688A0013800000A40401BE5E3\r
+S2140310B040301BE51664A0E1203063E235A3A0E1CF\r
+S2140310C02688A0E106C8A0E12CC8A0E13C300BE5C9\r
+S2140310D00A00A0E13933A0E10810A0E1155483E12A\r
+S2140310E048C00BE51F0100EB0810A0E10070A0E16B\r
+S2140310F00A00A0E1F50000EB48201BE52538A0E137\r
+S214031100900202E0077883E1020057E100A0A0E125\r
+S2140311101994A0E144800BE50500002A067097E0C9\r
+S21403112001A040E20200002A020057E101A04A3271\r
+S21403113006708730077062E044101BE50700A0E1E5\r
+S214031140080100EB44101BE50040A0E10700A0E106\r
+S214031150DE0000EB48201BE50538A0E1900202E024\r
+S2140311602338A0E1044883E1020054E10500002A85\r
+S214031170064094E0010040E20200002A020054E127\r
+S21403118001004032064084300AA880E1045062E041\r
+S2140311900628A0E12228A0E10810A0E10500A0E1AE\r
+S2140311A04C200BE5EF0000EB0810A0E10040A0E1A7\r
+S2140311B00500A0E1C50000EB4C201BE52938A0E1A3\r
+S2140311C0900202E0044883E1020054E10070A0E1CB\r
+S2140311D00500002A064094E0017040E20200002A5F\r
+S2140311E0020054E10170473206408430044062E056\r
+S2140311F00810A0E10400A0E1DA0000EB0810A0E16B\r
+S2140312000050A0E10400A0E1B00000EB4C201BE579\r
+S2140312100938A0E1900202E02338A0E1055883E1F3\r
+S214031220020055E10500002A065095E0010040E261\r
+S2140312300200002A020055E10650853001004032C4\r
+S21403124007C880E1059062E06DFFFFEA010456E3FC\r
+S2140312501800A0231000A03389FFFFEA010054E121\r
+S2140312600A00009A04309BE500A0A0E3000053E3C5\r
+S2140312700AC0A0E16EFFFF0A38000BE534100BE549\r
+S21403128030404BE2300014E9300083E868FFFFEAA1\r
+S214031290010854E38800002AFF0054E30800A083F3\r
+S2140312A00000A09320229FE53410A0E10130D2E78E\r
+S2140312B0003083E0203073E240300BE51200001A62\r
+S2140312C0040055E10600599140C01B350300003A5F\r
+S2140312D006C059E00450C5E00C90A0E101C0A0E3AD\r
+S2140312E004209BE500A0A0E3000052E350FFFF0AA2\r
+S2140312F034500BE538900BE530304BE2180013E919\r
+S2140313000250A0E1180082E849FFFFEA40C01BE54F\r
+S21403131040201BE520C06CE2363CA0E1144283E18A\r
+S2140313202438A0E135ACA0E150300BE53CC00BE51A\r
+S214031330393CA0E104C8A0E12CC8A0E10A00A0E162\r
+S21403134050101BE5155283E154C00BE5850000EBF6\r
+S21403135050101BE50080A0E10A00A0E15B0000EB53\r
+S21403136054201BE500A0A0E1920A0AE02538A0E17C\r
+S214031370088883E140301BE50A0058E158000BE576\r
+S2140313801663A0E11993A0E10700002A01C040E21A\r
+S214031390048098E058C00BE50300002A0A0058E1D1\r
+S2140313A001C04C3258C00B350480883008806AE090\r
+S2140313B050101BE50800A0E16A0000EB50101BE587\r
+S2140313C00070A0E10800A0E1400000EB54A01BE57C\r
+S2140313D00538A0E1900A0AE02338A0E1077883E104\r
+S2140313E00A0057E10500002A047097E0010040E276\r
+S2140313F00200002A0A0057E10100403204708730D9\r
+S21403140058201BE507706AE002C880E12C18A0E1AB\r
+S2140314102608A0E10128CCE10038C6E192030EE0DD\r
+S214031420910303E0900202E0910000E0022093E0C3\r
+S2140314300108802202E89EE02208A0E0070050E1AF\r
+S2140314400600008A0030A0130130A00309005EE105\r
+S2140314500030A09301300382000053E30300000A28\r
+S21403146006305EE00400C0E003E0A0E101C04CE209\r
+S21403147004409BE500A0A0E3000054E3ECFEFF0A53\r
+S21403148040201BE50E6059E00050C7E03C401BE5DA\r
+S2140314903632A0E1153483E13552A0E134500BE532\r
+S2140314A038300BE530504BE20690A0E104209BE574\r
+S2140314B0600015E9600082E8DDFEFFEA010454E3FC\r
+S2140314C01800A0231000A03375FFFFEAC02C03000A\r
+S2140314D0000051E31F00000A0130A0E30020A0E350\r
+S2140314E0010050E11900003A010251E300005131B6\r
+S2140314F00112A0310332A031FAFFFF3A020151E391\r
+S214031500000051318110A0318330A031FAFFFF3A39\r
+S214031510010050E10100402003208221A10050E198\r
+S214031520A1004020A3208221210150E12101402077\r
+S21403153023218221A10150E1A1014020A321822180\r
+S214031540000050E32332B0112112A011EFFFFF1A5F\r
+S2140315500200A0E10EF0A0E104E02DE5310000EB6F\r
+S2140315600000A0E30080BDE8000051E32900000A64\r
+S214031570010051E3010050110000A0030EF0A0315A\r
+S2140315800130A0E3010251E3000051310112A03102\r
+S2140315900332A031FAFFFF3A020151E30000513152\r
+S2140315A08110A0318330A031FAFFFF3A0020A0E378\r
+S2140315B0010050E101004020A10050E1A1004020BD\r
+S2140315C0E3208221210150E1210140206321822171\r
+S2140315D0A10150E1A1014020E321822103C0A0E143\r
+S2140315E0000050E32332B0112112A011EEFFFF1AC0\r
+S2140315F00E2212E207001C130500000AEC0112E19A\r
+S214031600A10180106C0112E121018010EC0012E1AF\r
+S214031610A10080100EF0A0E104E02DE5010000EB30\r
+S2100316200000A0E30080BDE80EF0A0E18F\r
+S21403162C6C6F6164000000004C6F6164206120667F\r
+S21403163C696C6500492F4F206572726F723A2025CC\r
+S21403164C730A00002563080043616E2774206C6FD1\r
+S21403165C616420272573273A2025730A00000000AF\r
+S21403166C43616E2774207265616420454C4620687E\r
+S21403167C65616465720A00004F6E6C792061627353\r
+S21403168C6F6C75746520454C4620696D6167657390\r
+S21403169C20737570706F727465640A00456E74728D\r
+S2140316AC7920706F696E743A2025702C20616464FF\r
+S2140316BC726573732072616E67653A2025702D25EB\r
+S2140316CC700A000041646472657373206F666673F8\r
+S2140316DC6574203D2025700A0000000053686F7265\r
+S2140316EC7420646174612072656164696E67204559\r
+S2140316FC4C462066696C65002A2A2A2041626F7262\r
+S21403170C742120417474656D707420746F206C6F33\r
+S21403171C616420454C46206461746120746F2061BB\r
+S21403172C6464726573733A202570207768696368FE\r
+S21403173C206973206E6F7420696E2052414D0A0027\r
+S21403174C43616E2774206C6F616420454C4620669B\r
+S21403175C696C65202D2070726F6772616D206865E9\r
+S21403176C6164657273206F7574206F66206F726484\r
+S21403177C65720A0043616E277420726561642045A6\r
+S21403178C4C462070726F6772616D20686561646584\r
+S21403179C720A0000546F6F206D616E792070726F41\r
+S2140317AC6772616D20686561646572730A00000078\r
+S2140317BC2A2A2A205761726E696E67212043686550\r
+S2140317CC636B73756D206661696C757265202D206D\r
+S2140317DC416464723A20256C782C202530326C5880\r
+S2140317EC203C3E202530326C580A00002A2A2A2038\r
+S2140317FC41626F72742120417474656D7074207429\r
+S21403180C6F206C6F616420532D7265636F72642056\r
+S21403181C746F20616464726573733A2025702C2090\r
+S21403182C7768696368206973206E6F7420696E200D\r
+S21403183C52414D0A00000000496E76616C696420C3\r
+S21403184C532D7265636F7264206174206F666673C2\r
+S21403185C6574203078256C782C20747970653A2062\r
+S21403186C25780A0042616420532D7265636F726497\r
+S21403187C20636F756E74206174206F66667365746F\r
+S21403188C2025700A00000000496E76616C6964209E\r
+S21403189C532D7265636F7264206174206F66667372\r
+S2140318AC65742025702C20696E7075743A20256338\r
+S2140318BC0A000000766572626F7365006C6F616474\r
+S2140318CC2072617720646174610000006C6F616440\r
+S2140318DC206164647265737300000000646F776E36\r
+S2140318EC6C6F6164206D6F64652028544654502CCD\r
+S2140318FC2078797A4D4F44454D2C206F72206469BD\r
+S21403190C736B290066696C65206E616D650000005B\r
+S21403191C454C4600556E7265636F676E697A6564EF\r
+S21403192C20696D61676520747970653A2030782577\r
+S21403193C6C780A002A2A2A2041626F72742120527C\r
+S21403194C41572064617461207370696C6C73206FEB\r
+S21403195C766572206C696D6974206F662075736585\r
+S21403196C722052414D2061742025700A000000003D\r
+S21403197C5261772066696C65206C6F6164656420C0\r
+S21403198C25702D25702C20617373756D6564206529\r
+S21403199C6E7472792061742025700A005261772068\r
+S2140319AC6C6F616420726571756972657320612052\r
+S2140319BC6D656D6F727920616464726573730A006A\r
+S2140319CC53706563696669656420616464726573E4\r
+S2140319DC732028257029206973206E6F7420626526\r
+S2140319EC6C696576656420746F20626520696E2069\r
+S2140319FC52414D0046696C65206E616D65207265BB\r
+S214031A0C7175697265640A0075736167653A206C53\r
+S214031A1C6F61642025730A00496E76616C696420D5\r
+S214031A2C276D6F6465273A2025732E202056616C2C\r
+S214031A3C6964206D6F646573206172653A000000FB\r
+S214031A4C4E6F2064656661756C742070726F746F6C\r
+S214031A5C636F6C210A00000043524300436B73759B\r
+S214031A6C6D00000078797A4D6F64656D202D202506\r
+S214031A7C73206D6F64652C20256428534F48292FDB\r
+S214031A8C256428535458292F25642843414E29206E\r
+S214031A9C7061636B6574732C202564207265747295\r
+S214031AAC6965730A0000000043616E277420616346\r
+S214031ABC636573732066696C65000000556E6B6E08\r
+S214031ACC6F776E206572726F72000000426C6F63E4\r
+S214031ADC6B2073657175656E6365206572726F72C4\r
+S214031AEC000000004352432F636865636B73756D88\r
+S214031AFC206572726F720000496E76616C696420A1\r
+S214031B0C6672616D696E670043616E63656C6C65C6\r
+S214031B1C64000000456E64206F662066696C650081\r
+S214031B2C54696D6564206F7574000000536F727290\r
+S214031B3C792C207A4D6F64656D206E6F74206176F8\r
+S214031B4C61696C61626C652079657400786D6F648D\r
+S214031B5C656D0000796D6F64656D00000000000014\r
+S214031B6C75736167653A20636B73756D202D622000\r
+S214031B7C3C616464723E202D6C203C6C656E67740D\r
+S214031B8C683E0A00436F6D707574696E6720636BED\r
+S214031B9C73756D20666F7220617265612025702DDA\r
+S214031BAC25700A00504F53495820636B73756D208C\r
+S214031BBC3D20256C7520256C75202830782530380B\r
+S214031BCC6C782030782530386C78290A00000000B1\r
+S214031BDC636B73756D000000436F6D7075746520D1\r
+S214031BEC6120333262697420636865636B73756D49\r
+S214031BFC205B504F53495820616C676F7269746849\r
+S214031C0C6D5D20666F7220612072616E6765206F52\r
+S214031C1C66206D656D6F7279000000002D62203CA6\r
+S214031C2C6C6F636174696F6E3E202D6C203C6C6523\r
+S214031C3C6E6774683E0000006261736520616464BD\r
+S214031C4C72657373000000006C656E677468000041\r
+S214031C5C75736167653A206D66696C6C202D62201E\r
+S214031C6C3C616464723E202D6C203C6C656E67741C\r
+S214031C7C683E205B2D70203C7061747465726E3EFA\r
+S214031C8C5D205B2D317C2D327C2D345D0A000000EB\r
+S214031C9C6D66696C6C00000046696C6C2061206292\r
+S214031CAC6C6F636B206F66206D656D6F7279207732\r
+S214031CBC6974682061207061747465726E0000002C\r
+S214031CCC2D62203C6C6F636174696F6E3E202D6CC5\r
+S214031CDC203C6C656E6774683E202D70203C7061EA\r
+S214031CEC747465726E3E205B2D317C2D327C2D34E4\r
+S214031CFC5D0000007061747465726E0066696C6CCE\r
+S214031D0C2033322062697420756E69747300000088\r
+S214031D1C66696C6C2031362062697420756E697442\r
+S214031D2C7300000066696C6C203820626974207539\r
+S214031D3C6E6974730000000075736167653A206DF5\r
+S214031D4C636D70202D73203C616464723E202D6499\r
+S214031D5C203C616464723E202D6C203C6C656E677F\r
+S214031D6C74683E205B2D317C2D327C2D345D0A004D\r
+S214031D7C4275666665727320646F6E2774206D6198\r
+S214031D8C746368202D2025703D3078253032782CEE\r
+S214031D9C2025703D3078253032780A004275666609\r
+S214031DAC65727320646F6E2774206D61746368208C\r
+S214031DBC2D2025703D3078253034782C2025703D29\r
+S214031DCC3078253034780A0042756666657273205F\r
+S214031DDC646F6E2774206D61746368202D202570E4\r
+S214031DEC3D3078253038782C2025703D30782530DA\r
+S214031DFC38780A006D636D7000000000436F6D70D9\r
+S214031E0C6172652074776F20626C6F636B73206FDF\r
+S214031E1C66206D656D6F7279000000002D73203C93\r
+S214031E2C6C6F636174696F6E3E202D64203C6C6F1F\r
+S214031E3C636174696F6E3E202D6C203C6C656E6717\r
+S214031E4C74683E205B2D317C2D327C2D345D000076\r
+S214031E5C75736167653A206D636F7079202D7320F7\r
+S214031E6C3C616464723E202D64203C616464723E63\r
+S214031E7C202D6C203C6C656E6774683E205B2D31A0\r
+S214031E8C7C2D327C2D345D0A00000000636F707964\r
+S214031E9C2033322062697420646174610000000090\r
+S214031EAC636F7079203136206269742064617461C3\r
+S214031EBC00000000636F7079203820626974206418\r
+S214031ECC617461006D636F7079000000436F707905\r
+S214031EDC206D656D6F72792066726F6D206F6E65FF\r
+S214031EEC206164647265737320746F20616E6F7403\r
+S214031EFC6865720053332530325825303858000045\r
+S214031F0C2530325800000000253032580A000000F5\r
+S214031F1C44756D702077686174205B6C6F636174B5\r
+S214031F2C696F6E5D3F0A000064756D7000000000FB\r
+S214031F3C446973706C617920286865782064756DC4\r
+S214031F4C702920612072616E6765206F66206D654F\r
+S214031F5C6D6F7279000000002D62203C6C6F63611C\r
+S214031F6C74696F6E3E205B2D6C203C6C656E6774DB\r
+S214031F7C683E5D205B2D735D205B2D317C327C349B\r
+S214031F8C5D00000064756D70206461746120757368\r
+S214031F9C696E67204D6F726F746F6C6120532D7270\r
+S214031FAC65636F726473000064756D702033322042\r
+S214031FBC62697420756E69747300000064756D70C5\r
+S214031FCC2031362062697420756E697473000000C4\r
+S214031FDC64756D7020382062697420756E6974732D\r
+S214031FEC0000000063616368650000004D616E616C\r
+S214031FFC6765206D616368696E65206361636865F8\r
+S21403200C730000005B4F4E207C204F46465D00005D\r
+S21403201C4F666600446174612063616368653A20A9\r
+S21403202C25732C20496E737472756374696F6E20F6\r
+S21403203C63616368653A2025730A00006F66660061\r
+S21403204C496E76616C6964206361636865206D6FA5\r
+S21403205C64653A2025730A0030313233343536370B\r
+S21403206C383961626364656600000000494E564168\r
+S21403207C4C4944004F4B0000503031004530310082\r
+S21403208C4530320045303300423031003031323384\r
+S21403209C3435363738394142434445460000000050\r
+S2140320AC303132333435363738394142434445467A\r
+S2140320BC00000000303132333435363738390000FF\r
+S2140320CC303132333435363738396162636465669A\r
+S2140320DC000000003C6E756C6C3E00003C4E6F744A\r
+S2140320EC206120737472696E673A203078000000A2\r
+S2140320FC3C42616420666F726D61742073747269FE\r
+S21403210C6E673A2000000000203A00003E0A0000EA\r
+S21403211C253038583A20000025303258200000006D\r
+S21403212C207C0000256300007C0A00002020200091\r
+S21403213C2530385820000000202020202020202086\r
+S21403214C200000002530345820000000766572739A\r
+S21403215C696F6E00446973706C61792052656442D2\r
+S21403216C6F6F742076657273696F6E20696E666F17\r
+S21403217C726D6174696F6E0068656C7000000000A8\r
+S21403218C48656C702061626F75742068656C703F6F\r
+S21403219C000000005B3C746F7069633E5D000000DA\r
+S2140321AC676F00004578656375746520636F6465B7\r
+S2140321BC2061742061206C6F636174696F6E00001C\r
+S2140321CC5B2D77203C74696D656F75743E5D205B83\r
+S2140321DC656E7472795D0000726573657400000039\r
+S2140321EC5265736574207468652073797374656DB2\r
+S2140321FC00000000453336303000000041524D20BD\r
+S21403220C39000000506C6174666F726D3A2025734A\r
+S21403221C20282573292025730A000000436F707944\r
+S21403222C72696768742028432920323030302C209A\r
+S21403223C323030312C20323030322C205265642030\r
+S21403224C4861742C20496E632E0A0A0052414D3A9B\r
+S21403225C2025702D25702C20000000005B25702D8A\r
+S21403226C25705D0020617661696C61626C650A009D\r
+S21403227C526564426F6F743E200000002A2A206366\r
+S21403228C6F6D6D616E642061626F7274202D2069B0\r
+S21403229C6C6C6567616C206D656D6F72792061631C\r
+S2140322AC636573733F0A00002A2A204572726F72A5\r
+S2140322BC3A20496C6C6567616C20636F6D6D616E5B\r
+S2140322CC643A20222573220A0000000025730A2094\r
+S2140322DC2025732025732025730A00003C746F7029\r
+S2140322EC69633E00496E76616C696420617267753A\r
+S2140322FC6D656E740A000000776169742074696DED\r
+S21403230C656F757400000000676F2077697468202A\r
+S21403231C63616368657320656E61626C6564000057\r
+S21403232C7374617274696E67206164647265737327\r
+S21403233C0000000041626F757420746F2073746123\r
+S21403234C727420657865637574696F6E206174208A\r
+S21403235C2570202D2061626F727420776974682053\r
+S21403236C5E432077697468696E2025642073656301\r
+S21403237C6F6E64730A0000000A50726F6772616DA9\r
+S21403238C20636F6D706C6574656420776974682060\r
+S21403239C7374617475732025640A00004E6F206590\r
+S2140323AC6E74727920706F696E74206B6E6F776EB5\r
+S2140323BC202D2061626F727465640A002E2E2E2007\r
+S2140323CC526573657474696E672E00002121206F45\r
+S2140323DC6F70732C205245534554206E6F742077C0\r
+S2140323EC6F726B696E67206F6E20746869732070EA\r
+S2140323FC6C6174666F726D0A000000006368616E30\r
+S21403240C6E656C00446973706C61792F73776974AD\r
+S21403241C636820636F6E736F6C65206368616E6EA2\r
+S21403242C656C00005B2D317C3C6368616E6E656C7D\r
+S21403243C206E756D6265723E5D00000043757272A8\r
+S21403244C656E7420636F6E736F6C65206368616E64\r
+S21403245C6E656C2069643A200000000025640A004F\r
+S21403246C2D310A002D3100002A2A204572726F7214\r
+S21403247C3A20696E76616C6964206368616E6E657A\r
+S21403248C6C20272573270A002A2A4572726F723A24\r
+S21403249C20626164206368616E6E656C206E756D78\r
+S2140324AC62657220272573270A0000005E430A0024\r
+S2140324BC202D20636F6E74696E75652028792F6ED8\r
+S2140324CC293F2000202A2A2054696D6564206F75E5\r
+S2140324DC74210A002121000025733A206576656E67\r
+S2140324EC74206E6F7420666F756E640A00000000AD\r
+S2140324FC2533642025730A00446973706C61792054\r
+S21403250C636F6D6D616E6420686973746F727900A6\r
+S21403251C556E62616C616E63656420737472696E6A\r
+S21403252C67210A00546F6F206D616E7920617267A4\r
+S21403253C756D656E7473202D2073746F707065647F\r
+S21403254C2061743A20272573270A0000416D6269BF\r
+S21403255C67756F757320636F6D6D616E64202725C9\r
+S21403256C73272C2063686F69636573206172653A01\r
+S21403257C2025730055736167653A0A00202025737E\r
+S21403258C25732025730A00002A2A204572726F725F\r
+S21403259C3A20696E76616C6964206E756D6265723D\r
+S2140325AC202725732720666F722025730A000000E8\r
+S2140325BC2A2A204572726F723A20257320616C7238\r
+S2140325CC65616479207370656369666965640A007E\r
+S2140325DC2A2A204572726F723A206E6F20646566E3\r
+S2140325EC61756C742F6E6F6E2D666C6167206172ED\r
+S2140325FC67756D656E747320737570706F72746522\r
+S21403260C640A00002A2A204572726F723A20696E99\r
+S21403261C76616C696420666C616720272563270ADC\r
+S21403262C000000007275650052554500616C7365B9\r
+S21403263C00000000414C534500000000465245453F\r
+S21403264C4D454D4C4F000000257000004652454545\r
+S21403265C4D454D48490000004E6F20726F6F6D203C\r
+S21403266C746F20657870616E6420272573270A00C3\r
+S21403267C416C6961732027257327206E6F74206461\r
+S21403268C6566696E65640A00496E76616C696420DA\r
+S21403269C6D6163726F2F616C6961732027257327D5\r
+S2140326AC0A00000001010101010101018080808004\r
+S2140326BC8080808000000000B71DC1046E3B820939\r
+S2140326CCD926430DDC7604136B6BC517B24D861AED\r
+S2140326DC0550471EB8ED08260FF0C922D6D68A2F0A\r
+S2140326EC61CB4B2B649B0C35D386CD310AA08E3C29\r
+S2140326FCBDBD4F3870DB114CC7C6D0481EE09345A2\r
+S21403270CA9FD5241ACAD155F1BB0D45BC296975670\r
+S21403271C758B5652C836196A7F2BD86EA60D9B63DB\r
+S21403272C11105A6714401D79A35DDC7D7A7B9F706C\r
+S21403273CCD665E74E0B6239857ABE29C8E8DA19162\r
+S21403274C399060953CC0278B8BDDE68F52FBA582B8\r
+S21403275CE5E66486585B2BBEEF46EABA3660A9B745\r
+S21403276C817D68B3842D2FAD3330EEA9EA16ADA464\r
+S21403277C5D0B6CA0906D32D42770F3D0FE56B0DD93\r
+S21403278C494B71D94C1B36C7FB06F7C32220B4CE74\r
+S21403279C953D75CA28803AF29F9DFBF646BBB8FB5F\r
+S2140327ACF1A679FFF4F63EE143EBFFE59ACDBCE8E0\r
+S2140327BC2DD07DEC77708634C06D4730194B043DB5\r
+S2140327CCAE56C539AB0682271C1B4323C53D002ECC\r
+S2140327DC7220C12ACF9D8E1278804F16A1A60C1B91\r
+S2140327EC16BBCD1F13EB8A01A4F64B057DD0080848\r
+S2140327FCCACDC90C07AB9778B0B6567C69901571E1\r
+S21403280CDE8DD475DBDD936B6CC0526FB5E611624F\r
+S21403281C02FBD066BF469F5E085B5E5AD17D1D5792\r
+S21403282C6660DC5363309B4DD42D5A490D0B19440B\r
+S21403283CBA16D84097C6A5AC20DB64A8F9FD27A525\r
+S21403284C4EE0E6A14BB0A1BFFCAD60BB258B23B617\r
+S21403285C9296E2B22F2BAD8A98366C8E41102F834C\r
+S21403286CF60DEE87F35DA9994440689D9D662B9003\r
+S21403287C2A7BEA94E71DB4E0500075E4892636E912\r
+S21403288C3E3BF7ED3B6BB0F38C7671F7555032FA53\r
+S21403289CE24DF3FE5FF0BCC6E8ED7DC231CB3ECF16\r
+S2140328AC86D6FFCB8386B8D5349B79D1EDBD3ADC7F\r
+S2140328BC5AA0FBD8EEE00C6959FDCD6D80DB8E601B\r
+S2140328CC37C64F643296087A858BC97E5CAD8A739D\r
+S2140328DCEBB04B77560D044FE110C54B3836864696\r
+S2140328EC8F2B47428A7B005C3D66C158E440825579\r
+S2140328FC535D43519E3B1D252926DC21F0009F2C5E\r
+S21403290C471D5E28424D1936F550D8322C769B3F20\r
+S21403291C9B6B5A3B26D6150391CBD40748ED970AE7\r
+S21403292CFFF0560EFAA011104DBDD014949B9319BC\r
+S21403293C2386521D0E562FF1B94BEEF5606DADF88E\r
+S21403294CD7706CFCD2202BE2653DEAE6BC1BA9EBE8\r
+S21403295C0B0668EFB6BB27D701A6E6D3D880A5DE51\r
+S21403296C6F9D64DA6ACD23C4DDD0E2C004F6A1CD34\r
+S21403297CB3EB60C97E8D3EBDC990FFB910B6BCB42F\r
+S21403298CA7AB7DB0A2FB3AAE15E6FBAACCC0B8A7A4\r
+S21403299C7BDD79A3C660369B717DF79FA85BB492EB\r
+S2140329AC1F4675961A163288AD0BF38C742DB081B0\r
+S2140329BCC330718599908A5D2E8D4B59F7AB0854AD\r
+S2140329CC40B6C95045E68E4EF2FB4F4A2BDD0C47FC\r
+S2140329DC9CC0CD43217D827B9660437F4F4600721D\r
+S2140329ECF85BC176FD0B86684A16476C9330046118\r
+S2140329FC242DC565E94B9B115E565A15877019181D\r
+S214032A0C306DD81C353D9F0282205E065B061D0B7F\r
+S214032A1CEC1BDC0F51A69337E6BB52333F9D113E9E\r
+S214032A2C8880D03A8DD097243ACD5620E3EB152DDB\r
+S214032A3C54F6D4297926A9C5CE3B68C1171D2BCCD1\r
+S214032A4CA000EAC8A550ADD6124D6CD2CB6B2FDFC7\r
+S214032A5C7C76EEDBC1CBA1E376D660E7AFF023EA58\r
+S214032A6C18EDE2EE1DBDA5F0AAA064F4738627F953\r
+S214032A7CC49BE6FD09FDB889BEE0798D67C63A802E\r
+S214032A8CD0DBFB84D58BBC9A62967D9EBBB03E9303\r
+S214032A9C0CADFF97B110B0AF060D71ABDF2B32A6A2\r
+S214032AAC6836F3A26D66B4BCDA7B75B8035D36B5CF\r
+S214032ABCB440F7B100002110422063308440A55087\r
+S214032ACCC660E770088129914AA16BB18CC1ADD160\r
+S214032ADCCEE1EFF13112100273325222B552944208\r
+S214032AECF772D662399318837BB35AA3BDD39CC3B0\r
+S214032AFCFFF3DEE36224433420040114E664C77454\r
+S214032B0CA44485546AA54BB528850995EEE5CFF5FF\r
+S214032B1CACC58DD55336722611163006D776F666A7\r
+S214032B2C9556B4465BB77AA719973887DFF7FEE74F\r
+S214032B3C9DD7BCC7C448E5588668A7784008611873\r
+S214032B4C02282338CCC9EDD98EE9AFF9488969999F\r
+S214032B5C0AA92BB9F55AD44AB77A966A711A500A47\r
+S214032B6C333A122AFDDBDCCBBFFB9EEB799B588BEF\r
+S214032B7C3BBB1AABA66C877CE44CC55C222C033C93\r
+S214032B8C600C411CAEED8FFDECCDCDDD2AAD0BBD3F\r
+S214032B9C688D499D977EB66ED55EF44E133E322EE7\r
+S214032BAC511E700E9FFFBEEFDDDFFCCF1BBF3AAF8F\r
+S214032BBC599F788F8891A981CAB1EBA10CD12DC1ED\r
+S214032BCC4EF16FE18010A100C230E3200450254083\r
+S214032BDC46706760B9839893FBA3DAB33DC31CD3E3\r
+S214032BEC7FE35EF3B1029012F322D23235421452D3\r
+S214032BFC77625672EAB5CBA5A89589856EF54FE52F\r
+S214032C0C2CD50DC5E234C324A01481046674476422\r
+S214032C1C24540544DBA7FAB79987B8975FE77EF782\r
+S214032C2C1DC73CD7D326F2369106B0165766767672\r
+S214032C3C154634564CD96DC90EF92FE9C899E9894E\r
+S214032C4C8AB9ABA94458654806782768C018E108C2\r
+S214032C5C8238A3287DCB5CDB3FEB1EFBF98BD89B22\r
+S214032C6CBBAB9ABB754A545A376A167AF10AD01A12\r
+S214032C7CB32A923A2EFD0FED6CDD4DCDAABD8BAD6E\r
+S214032C8CE89DC98D267C076C645C454CA23C832C62\r
+S214032C9CE01CC10C1FEF3EFF5DCF7CDF9BAFBABFC2\r
+S214032CACD98FF89F176E367E554E745E932EB23EB2\r
+S214032CBCD10EF01E000102020303030304040404F2\r
+S214032CCC04040404050505050505050505050505A4\r
+S214032CDC0505050506060606060606060606060684\r
+S214032CEC0606060606060606060606060606060670\r
+S214032CFC0606060607070707070707070707070754\r
+S214032D0C070707070707070707070707070707073F\r
+S214032D1C070707070707070707070707070707072F\r
+S214032D2C070707070707070707070707070707071F\r
+S214032D3C0707070708080808080808080808080803\r
+S214032D4C08080808080808080808080808080808EF\r
+S214032D5C08080808080808080808080808080808DF\r
+S214032D6C08080808080808080808080808080808CF\r
+S214032D7C08080808080808080808080808080808BF\r
+S214032D8C08080808080808080808080808080808AF\r
+S214032D9C080808080808080808080808080808089F\r
+S214032DAC080808080808080808080808080808088F\r
+S208032DBC08080808EB\r
+S214032DC00000000098B5020098B5020098B502000E\r
+S214032DD098B5020098B5020098B5020098B50200AF\r
+S214032DE098B5020098B5020098B5020098B502009F\r
+S214032DF098B5020098B5020098B5020098B502008F\r
+S214032E0098B5020098B5020098B5020098B502007E\r
+S214032E1098B5020098B5020098B5020098B502006E\r
+S214032E2098B5020098B5020098B5020098B502005E\r
+S214032E3098B5020098B5020098B5020098B502004E\r
+S214032E4098B5020098B5020098B5020098B502003E\r
+S214032E5098B5020098B5020098B5020098B502002E\r
+S214032E6098B5020098B5020098B5020098B502001E\r
+S214032E7098B5020098B5020098B5020098B502000E\r
+S214032E8098B5020098B5020098B5020098B50200FE\r
+S214032E9098B5020098B5020098B5020098B50200EE\r
+S214032EA098B5020098B5020098B5020098B50200DE\r
+S214032EB098B5020098B5020098B5020098B50200CE\r
+S214032EC098B5020098B5020000000000000000005C\r
+S214032ED000000000000000000000000000000000EA\r
+S214032EE000000000000000000000000000000000DA\r
+S214032EF000000000000000000000000000000000CA\r
+S214032F0000000000000000000000000000000000B9\r
+S214032F1000000000000000000000000000000000A9\r
+S214032F200000000000000000000000000000000099\r
+S214032F300000000000000000000000000000000089\r
+S214032F400000000000000000000000000000000079\r
+S214032F500000000000000000000000000000000069\r
+S214032F600000000000000000000000000000000059\r
+S214032F700000000000000000000000000000000049\r
+S214032F800000000000000000000000000000000039\r
+S214032F900000000000000000000000000000000029\r
+S214032FA00000000000000000000000000000000019\r
+S214032FB00000000000000000000000000000000009\r
+S214032FC000000000000000000000000000000000F9\r
+S214032FD000000000000000000000000000000000E9\r
+S214032FE000000000000000000000000000000000D9\r
+S214032FF000000000000000000000000000000000C9\r
+S21403300000000000000000000000000000000000B8\r
+S21403301000000000000000000000000000000000A8\r
+S2140330200000000000000000000000000000000098\r
+S2140330300000000000000000000000000000000088\r
+S2140330400000000000000000000000000000000078\r
+S2140330500000000000000000000000000000000068\r
+S2140330600000000000000000000000000000000058\r
+S2140330700000000000000000000000000000000048\r
+S2140330800000000000000000000000000000000038\r
+S2140330900000000000000000000000000000000028\r
+S2140330A00000000000000000000000000000000018\r
+S2140330B00000000000000000000000000000000008\r
+S2140330C000000000000000000000000000000000F8\r
+S2140330D00A526564426F6F7428746D2920626F6F9D\r
+S2140330E074737472617020616E64206465627567C0\r
+S2140330F020656E7669726F6E6D656E74205B5241E5\r
+S2140331004D5D0A4E6F6E2D636572746966696564FC\r
+S2140331102072656C656173652C2076657273696FC2\r
+S2140331206E20554E4B4E4F574E202D206275696CC0\r
+S214033130742031313A34343A35312C204D617920BC\r
+S214033140203920323030350A0A0000005B2D725DCC\r
+S214033150205B2D765D205B2D68203C686F73743E84\r
+S2140331605D205B2D6D203C7661726965733E5D2044\r
+S2140331700A20202020202020205B2D62203C626134\r
+S21403318073655F616464726573733E5D203C666954\r
+S2140331906C655F6E616D653E000000007C2F2D5CE4\r
+S2140331A07C2D000034790200907D0200EC7D020045\r
+S2140331B0D07A0200247F02000100000020000000F5\r
+S2140331C00000000000000000E0A3020034A4020098\r
+S2140331D0000000000000000000000000FFFFFFFFEB\r
+S2140331E00000000000000000208103000000000033\r
+S2140331F00000000000000000FEFFFFFFFEFFFFFFD1\r
+S21403320000000000000000005CB60200FFFFFFFFA6\r
+S214033210FFFFFFFF000000000000000000000000AA\r
+S21403322000000780E80300000000000000C00680DE\r
+S214033230E803000017000000000000000000000084\r
+S2140332400200000000000000000000000000000074\r
+S2140332500000000000000000000000000000000066\r
+S2140332600000000000000000000000000000000056\r
+S2140332700000000000000000000000000000000046\r
+S2140332800000000000000000000000000000000036\r
+S214033290C05D000000000000E8030000000000001E\r
+S2140332A0F01F0300F81F030010200300A08C020089\r
+S2140332B000000000000000000824030010240300A0\r
+S2140332C03024030070D1020000000000000000005C\r
+S2140332D0DC1B0300E41B0300281C0300C07F020062\r
+S2140332E00000000000000000341F03003C1F030022\r
+S2140332F0641F030050890200000000000000000065\r
+S214033300AC210300B0210300CC210300A4CD0200AE\r
+S2140333100000000000000000842103008C2103004D\r
+S214033320A0210300C8CC020000000000000000003B\r
+S2140333301425030004250300681B030040E0020075\r
+S21403334000000000000000002C16030034160300E3\r
+S2140333504C3103002471020000000000000000004E\r
+S214033360001E0300081E0300281E03009C830200A1\r
+S2140333700000000000000000D01E0300D81E03005B\r
+S214033380281E0300948602000000000000000000D0\r
+S2140333909C1C0300A41C0300CC1C03003881020001\r
+S2140333A00000000000000000E4210300EC210300FD\r
+S2140333B0681B030010D0020000000000000000009D\r
+S2140333C05821030060210300681B030058C702004E\r
+S2140333D00000000000000000F82003003C1F03006C\r
+S2140333E0641F0300948C020000000000000000002D\r
+S2140333F0581B0300A4310300000000000000000077\r
+S21403340001000000601B0300A4310300000000005D\r
+S21003341000000000020000007CC6020062\r
+S80402604059\r
diff --git a/tools/elftosb/test_files/rom_nand_ldr_profile b/tools/elftosb/test_files/rom_nand_ldr_profile
new file mode 100644 (file)
index 0000000..2ac9ed7
Binary files /dev/null and b/tools/elftosb/test_files/rom_nand_ldr_profile differ
diff --git a/tools/elftosb/test_files/sd_player_gcc b/tools/elftosb/test_files/sd_player_gcc
new file mode 100644 (file)
index 0000000..ba1fb08
Binary files /dev/null and b/tools/elftosb/test_files/sd_player_gcc differ
diff --git a/tools/elftosb/test_files/sd_player_gcc.srec b/tools/elftosb/test_files/sd_player_gcc.srec
new file mode 100644 (file)
index 0000000..3155c7c
--- /dev/null
@@ -0,0 +1,11250 @@
+S011000073645F706C617965722E7372656350\r
+S3150000680018F09FE518F09FE518F09FE518F09FE552\r
+S3150000681018F09FE50000000018F09FE518F09FE5CE\r
+S3150000682040680000546A0000786A0000A46A00000C\r
+S31500006830C06A000000000000CC6B0000886B0000FE\r
+S31500006840100F11EE020AC0E30400C0E3010AC0E320\r
+S315000068500100C0E368159FE5010000E064159FE5AF\r
+S31500006860010080E1100F01EE0000A0E10000A0E1B0\r
+S315000068700000A0E10000A0E10000A0E10000A0E10E\r
+S315000068800000A0E10000A0E10000A0E3160F07EE63\r
+S31500006890150F07EEA201A0E32C159FE5001080E579\r
+S315000068A028159FE528059FE5001080E524059FE54E\r
+S315000068B0001080E520059FE5001080E51C059FE59A\r
+S315000068C0001080E518059FE5001080E514059FE59A\r
+S315000068D0001080E510059FE5001080E50C059FE59A\r
+S315000068E0001080E508059FE5001080E504059FE59A\r
+S315000068F0001080E500059FE5001080E5FC049FE59B\r
+S31500006900001080E5F8049FE5001080E5F4049FE59B\r
+S31500006910001080E5F0049FE5001080E5EC049FE59B\r
+S31500006920001080E59201A0E30318A0E3001080E5C3\r
+S31500006930DC049FE50010A0E3001080E5001080E570\r
+S3150000694000700FE11F7007E2130057E30700000A0B\r
+S315000069500000A0E3BC149FE5042091E5042080E537\r
+S31500006960242091E5242080E5082091E5082080E593\r
+S3150000697028049FE5001090E5000051E3FDFFFF1A93\r
+S31500006980C8109FE5001080E50000A0E308149FE50D\r
+S31500006990130057E30100000A282091E5282080E52E\r
+S315000069A0182091E5182080E5382091E5382080E50B\r
+S315000069B01C2091E51C2080E53C2091E53C2080E5EB\r
+S315000069C00C2091E50C2080E52C2091E52C2080E51B\r
+S315000069D0102091E5102080E5302091E5302080E5FB\r
+S315000069E084D39FE5D200A0E300F029E17CD39FE5A4\r
+S315000069F0DB00A0E300F029E170D39FE5D300A0E31C\r
+S31500006A0000F029E100F069E19CD39FE564139FE55E\r
+S31500006A1064239FE50000A0E3020051E10200000AA2\r
+S31500006A20040081E4020051E1FCFFFF9A845100EB6F\r
+S31500006A30462D00EB495100EBDC139FE501D0A0E1A8\r
+S31500006A400F2F00EBFEFFFFEA0000A0E300F0A0E13D\r
+S31500006A500BB0ADDE18D39FE53F002DE900104FE1E6\r
+S31500006A60200011E304004E0202004E120120A0E3B2\r
+S31500006A700D30A0E1180000EA00012DE9F0829FE543\r
+S31500006A803F0028E90830A0E10001BDE800104FE111\r
+S31500006A90200011E304004E0202004E120220A0E381\r
+S31500006AA00D0000EAC8D29FE53F002DE904004EE242\r
+S31500006AB000104FE10320A0E30D30A0E1060000EA3C\r
+S31500006AC0ACD29FE53F002DE904004EE200104FE1F5\r
+S31500006AD00420A0E30D30A0E1FFFFFFEA00400FE134\r
+S31500006AE01F40C4E3134084E304F029E10D50A0E104\r
+S31500006AF00E40A0E137002DE90D00A0E100200FE1D6\r
+S31500006B00C01081E32010C1E301F029E1007F20E9F4\r
+S31500006B1002F029E100D0A0E13F0093E8FF002DE953\r
+S31500006B2040109DE51F1001E2130051E34C109D0536\r
+S31500006B3034108D050D00A0E1F55000EB40009DE5F9\r
+S31500006B401F1000E2130051E300F069E1FFFFDD08CA\r
+S31500006B5020208DE200100FE1C00080E32000C0E39A\r
+S31500006B6000F029E1007F92E801F029E14C009DE563\r
+S31500006B7020008DE548009DE524008DE53C009DE55F\r
+S31500006B8028008DE5FFE0DDE80180A0E38C929FE51B\r
+S31500006B90008089E500804FE11F9008E2120059E36A\r
+S31500006BA00200001A408088E308F069E104F05EE222\r
+S31500006BB0B8D19FE500410DE9D280A0E308F029E1B4\r
+S31500006BC0A8D19FE500601DE90DF069E19CD19FE524\r
+S31500006BD03F002DE904004EE200104FE10620A0E33D\r
+S31500006BE00D30A0E100400FE11F40C4E3134084E3F1\r
+S31500006BF004F029E10D50A0E10E40A0E137002DE997\r
+S31500006C000D00A0E100200FE1C01081E32010C1E3D8\r
+S31500006C1001F029E1007F20E902F029E100D0A0E19E\r
+S31500006C203F0093E8FF002DE940109DE51F1001E2AB\r
+S31500006C30130051E34C109D0534108D050D90A0E115\r
+S31500006C4060219FE5000092E5011080E2001082E5D8\r
+S31500006C50000050E30D10A0014CD19F0502002D0944\r
+S31500006C603C319FE5004093E5014084E2004083E526\r
+S31500006C700900A0E1535100EB0040A0E10400A0E1AF\r
+S31500006C809C219FE5009082E5010070E30200001A56\r
+S31500006C900900A0E1B05000EB060000EAF0109FE505\r
+S31500006CA0041191E7E4209FE5046192E70920A0E141\r
+S31500006CB00FE0A0E106F0A0E1E8209FE500100FE15B\r
+S31500006CC0C03081E303F029E1003092E5013053E260\r
+S31500006CD0003082E500D09D0501F029E1010074E352\r
+S31500006CE00300000AAC109FE5041191E70920A0E11A\r
+S31500006CF0B93A00EB90FFFFEA30402DE900400FE182\r
+S31500006D00C02084E3C050C4E302F029E10D30A0E1C5\r
+S31500006D1094D09FE508002DE988209FE5003092E594\r
+S31500006D20013083E2003082E505F029E18A3A00EB82\r
+S31500006D3000100FE1C02081E302F029E164209FE505\r
+S31500006D40003092E5013043E2003082E500D09DE557\r
+S31500006D5004F029E13080BDE80EF0A0E100000FE16B\r
+S31500006D600EF0A0E10D00A0E10EF0A0E170350200EA\r
+S31500006D70E0220200602302006022020064B20200E8\r
+S31500006D8064B2020000140200001402006022020035\r
+S31500006D9004140200081502000C1602000068000028\r
+S31500006DA000140200F4200200603302006033020087\r
+S31500006DB065436F73203A20004F63742020342032DD\r
+S31500006DC030303500FFF3050078000500000003C0F1\r
+S31500006DD00F0F0F0F68000080780000808800008089\r
+S31500006DE098000080A8000080B8000080C8000080DD\r
+S31500006DF0D8000080E8000080F800008008010080CC\r
+S31500006E0018010080280100803801008048010080B8\r
+S31500006E105801008000C00180006800007035020043\r
+S31500006E206021020020B202000DC0A0E130D82DE999\r
+S31500006E3004B04CE260D04DE274004BE2C0109FE516\r
+S31500006E406020A0E30F49A0E3663200EB0400A0E156\r
+S31500006E50100F02EE0000E0E3100F03EE0400A0E1C5\r
+S31500006E600129A0E30010A0E38E3200EB0050A0E35E\r
+S31500006E7014E04BE25C301EE500C0A0E303005CE1D9\r
+S31500006E801400002A60201EE50C2082E0023194E7FF\r
+S31500006E9054101EE5233AA0E1013683E16336A0E1F2\r
+S31500006EA0023184E760101EE50C1081E0013194E7A1\r
+S31500006EB058201EE5FF34C3E30C2082E00F36C3E3FF\r
+S31500006EC0023A83E1013184E75C301EE501C08CE2C1\r
+S31500006ED003005CE1EAFFFF3A015085E2050055E355\r
+S31500006EE010E08EE2E2FFFF9A100F11EE010A80E336\r
+S31500006EF0040080E3020080E3010080E3100F01EE4E\r
+S31500006F0030A81BE92C0802000130A0E10010A0E324\r
+S31500006F10010010E3A000A0E10200001A011081E2C6\r
+S31500006F20200051E3F9FFFFDA1301A0E10EF0A0E122\r
+S31500006F300130A0E10010A0E3010010E3A000A0E1F1\r
+S31500006F400200001A011081E2200051E3F9FFFFDA86\r
+S31500006F503301A0E10EF0A0E10DC0A0E170D82DE94B\r
+S31500006F600048A0E104B04CE208D04DE24448A0E15C\r
+S31500006F700150A0E10260A0E10030A0E37AFF17EE25\r
+S31500006F80FDFFFF1A9A3F07EE0419A0E101C0A0E336\r
+S31500006F902118A0E11C204BE2043083E2C000A0E3EC\r
+S31500006FA000C08DE5231F00EB0030A0E37AFF17EE4B\r
+S31500006FB0FDFFFF1A9A3F07EE1C301BE50500A0E116\r
+S31500006FC00530C3E10610A0E11C300BE5CDFFFFEB59\r
+S31500006FD01C301BE518204BE2003083E1043022E52B\r
+S31500006FE00030A0E37AFF17EEFDFFFF1A9A3F07EE87\r
+S31500006FF00449A0E12448A0E101C0A0E30410A0E1F7\r
+S31500007000043083E2C000A0E300C08DE5B61E00EBAD\r
+S315000070100030A0E37AFF17EEFDFFFF1A9A3F07EE56\r
+S3150000702070A81BE90DC0A0E110D82DE90008A0E169\r
+S3150000703004B04CE208D04DE24008A0E10140A0E1D6\r
+S315000070400030A0E37AFF17EEFDFFFF1A9A3F07EE26\r
+S315000070500009A0E12008A0E10010A0E101C0A0E322\r
+S3150000706014204BE2043083E2C000A0E300C08DE5AB\r
+S31500007070F01E00EB0030A0E37AFF17EEFDFFFF1ACB\r
+S315000070809A3F07EE0400A0E114101BE5A7FFFFEBF3\r
+S3150000709010A81BE90DC0A0E110D82DE994429FE588\r
+S315000070A0003094E5013083E2030053E3003084E5C9\r
+S315000070B00030A0C3003084C504B04CE2672000EB6A\r
+S315000070C0003094E5030053E303F19F97100000EAB4\r
+S315000070D0E0700000AC720000D8720000047300007B\r
+S315000070E00040E0E350229FE50410A0E10000A0E389\r
+S315000070F098FFFFEB44229FE50410A0E10100A0E306\r
+S3150000710094FFFFEB38229FE50010A0E33800A0E3D0\r
+S31500007110DF1500EB0713A0E30120A0E30600A0E3C0\r
+S315000071208CFFFFEB0A00A0E3260F00EB1A00A0E39A\r
+S315000071307F10A0E3BAFFFFEB630050E3020000DA22\r
+S31500007140640050E35400000A530000CA0713A0E38A\r
+S315000071500520A0E30600A0E37EFFFFEB0A00A0E304\r
+S31500007160180F00EB1A00A0E37F10A0E3ACFFFFEBC3\r
+S31500007170630050E3020000DA640050E34600000AB0\r
+S31500007180450000CA0400A0E30C10A0E30220A0E31F\r
+S3150000719070FFFFEB1D00A0E3FF14A0E3A0FFFFEBD1\r
+S315000071A0180050E3380000DA190050E33600000AF0\r
+S315000071B01D00A0E3FF14A0E399FFFFEBE60050E3F8\r
+S315000071C0020000DAE70050E32F00000A2E0000CA92\r
+S315000071D070419FE50219A0E30120A0E30200A0E3AD\r
+S315000071E05CFFFFEB0500A0E3F60E00EB58219FE5E0\r
+S315000071F00410A0E10200A0E356FFFFEB0300A0E3AA\r
+S31500007200F00E00EB44219FE50410A0E10200A0E38C\r
+S3150000721050FFFFEB0300A0E3EA0E00EB30219FE5F1\r
+S315000072200410A0E10200A0E34AFFFFEB0400A0E384\r
+S31500007230E40E00EB1C219FE50410A0E10200A0E390\r
+S3150000724044FFFFEB0A00A0E3DE0E00EB08219FE5FA\r
+S315000072500410A0E10200A0E33EFFFFEB1900A0E34B\r
+S31500007260D80E00EBF4209FE50410A0E10200A0E395\r
+S3150000727038FFFFEB0110A0E31700A0E30120A0E117\r
+S3150000728034FFFFEB10681BE9B51F00EA0200A0E31C\r
+S315000072900219A0E30020A0E3F4FFFFEA0400A0E344\r
+S315000072A00C10A0E30020A0E3B8FFFFEA0040E0E3F3\r
+S315000072B0AC209FE50410A0E10000A0E325FFFFEB52\r
+S315000072C0A0209FE50410A0E10100A0E321FFFFEB51\r
+S315000072D094209FE58BFFFFEA0040E0E38C209FE5CA\r
+S315000072E00410A0E10000A0E31AFFFFEB80209FE559\r
+S315000072F00410A0E10100A0E316FFFFEB74209FE558\r
+S3150000730080FFFFEA0040E0E36C209FE50000A0E379\r
+S315000073100410A0E10FFFFFEB0410A0E15C209FE545\r
+S315000073200100A0E30BFFFFEB54209FE53800A0E32C\r
+S315000073300010A0E375FFFFEA28170200F64E0400CE\r
+S3150000734004F7111C8C080200FFFF0000A582000054\r
+S3150000735095830000748400003585000032860000A5\r
+S3150000736010880000014F0400F0BC5E1C9808020063\r
+S31500007370165104008FE03E1CA40802001A510400B6\r
+S3150000738097D15C1CB00802000DC0A0E170D82DE9B1\r
+S3150000739004B04CE20050A0E1B01F00EBCCC19FE569\r
+S315000073A0CC319FE5CC419FE585C08CE00060E0E3F1\r
+S315000073B000C083E5852194E70000A0E30610A0E164\r
+S315000073C0854184E0E3FEFFEB042094E50610A0E18E\r
+S315000073D00100A0E3DFFEFFEB0713A0E30120A0E31B\r
+S315000073E00600A0E3DBFEFFEB0A00A0E3750E00EB50\r
+S315000073F01A00A0E37F10A0E309FFFFEB630050E350\r
+S315000074000200009A640050E35400000A5300008A08\r
+S315000074100713A0E30520A0E30600A0E3CDFEFFEBE3\r
+S315000074200A00A0E3670E00EB1A00A0E37F10A0E3BA\r
+S31500007430FBFEFFEB630050E30200009A640050E39A\r
+S315000074404600000A4500008A0400A0E30C10A0E3F1\r
+S315000074500220A0E3BFFEFFEB1D00A0E3FF14A0E3A4\r
+S31500007460EFFEFFEB180050E33800009A190050E3D6\r
+S315000074703600000A1D00A0E3FF14A0E3E8FEFFEBC0\r
+S31500007480E60050E30200009AE70050E32F00000AEE\r
+S315000074902E00008AE0409FE50219A0E30120A0E348\r
+S315000074A00200A0E3ABFEFFEB0500A0E3450E00EBF8\r
+S315000074B0C8209FE50410A0E10200A0E3A5FEFFEBB3\r
+S315000074C00300A0E33F0E00EBB4209FE50410A0E10B\r
+S315000074D00200A0E39FFEFFEB0300A0E3390E00EBE2\r
+S315000074E0A0209FE50410A0E10200A0E399FEFFEBB7\r
+S315000074F00400A0E3330E00EB8C209FE50410A0E10E\r
+S315000075000200A0E393FEFFEB0A00A0E32D0E00EBC2\r
+S3150000751078209FE50410A0E10200A0E38DFEFFEBBA\r
+S315000075201900A0E3270E00EB64209FE50410A0E1FC\r
+S315000075300200A0E387FEFFEB0110A0E31700A0E323\r
+S315000075400120A0E183FEFFEB70681BE9041F00EA3F\r
+S315000075500200A0E30219A0E30020A0E3F4FFFFEA83\r
+S315000075600400A0E30C10A0E30020A0E3B8FFFFEAAC\r
+S315000075707103000010170200B01C0200FFFF00009C\r
+S31500007580A582000095830000748400003585000004\r
+S3150000759032860000108800004C309FE54C209FE5A5\r
+S315000075A0803083E09203C1E00DC0A0E110D82DE940\r
+S315000075B0C32FA0E104B04CE2412162E0021182E057\r
+S315000075C030404BE220D04DE2813043E00400A0E1A0\r
+S315000075D01C109FE5CE4200EB0420A0E10010A0E3C2\r
+S315000075E03800A0E3AA1400EB10A81BE97103000001\r
+S315000075F067666666BC0802000DC0A0E1F0DF2DE9F3\r
+S3150000760004B04CE220D04DE2141F00EBD0319FE5D0\r
+S315000076100020A0E3B020C3E1011082E20138A0E11E\r
+S315000076200228A0E11D0853E3B8319FE5C227A0E177\r
+S315000076300040A0E3B34082E10120A0E1F5FFFFDABC\r
+S315000076409C319FE500C0E0E3B0C0C3E198319FE5FF\r
+S3150000765098219FE51000A0E30410A0E1B040C3E12B\r
+S315000076608B1400EB88919FE504A0A0E1AA3F8AE075\r
+S3150000767080419FE5C380A0E10060E0E3882194E7B4\r
+S315000076800000A0E30610A0E1884184E031FEFFEB94\r
+S31500007690042094E50100A0E30610A0E12DFEFFEB17\r
+S315000076A00610A0E11C00A0E35DFEFFEB48719FE51C\r
+S315000076B0070000E01F2000E2A032A0E10610A0E1D2\r
+S315000076C01C00A0E31352A0E155FEFFEB2C419FE501\r
+S315000076D0070000E0043000E01F2000E2A332A0E132\r
+S315000076E00610A0E11C00A0E3135285E04CFEFFEB60\r
+S315000076F0070000E0044000E01F2000E2A432A0E101\r
+S31500007700135285E0F8309FE5952383E0D0009FE58E\r
+S31500007710A330A0E10F0053E30050A0E1029089E2FC\r
+S3150000772002A08AE20600009AB030D0E1013083E27E\r
+S315000077300328A0E1AC109FE5C227A0E1B18082E159\r
+S31500007740B030C0E1F020D5E11D0052E30200000A8E\r
+S31500007750B0309FE5030059E1C3FFFFDA48404BE232\r
+S31500007760A4109FE50400A0E1694200EB0420A0E11B\r
+S315000077701000A0E30010A0E3451400EBB030D5E103\r
+S315000077800338A0E14308B0E11300000AA33F80E0FC\r
+S3150000779050409FE50130C3E3B40093E1F9FEFFEBEF\r
+S315000077A0B020D5E10228A0E1A23FA0E1423883E063\r
+S315000077B00130C3E3B40093E176FFFFEBB030D5E1CF\r
+S315000077C00338A0E1A32FA0E1432882E018309FE50B\r
+S315000077D0C220A0E1B020C3E1F0AF1BE9E9FEFFEB58\r
+S315000077E0F0AF1BE92C17020000B102002E170200B1\r
+S315000077F0CC08020071030000B01C0200FFFF00006D\r
+S31500007800E0FF0000ABAAAAAA38040000D8080200CC\r
+S315000078100DC0A0E130D82DE954309FE5F010D3E13A\r
+S31500007820010071E304B04CE248509FE548409FE5F3\r
+S3150000783030A81B09B030D4E1013083E20328A0E16F\r
+S31500007840420851E1B030C4E10030A003B030C401B9\r
+S31500007850F030D4E18330A0E1B50093E1C9FEFFEB3F\r
+S31500007860F030D4E18330A0E1B50093E130681BE944\r
+S3150000787048FFFFEA2C17020000B102002E17020093\r
+S315000078800DC0A0E130D82DE954209FE5F030D2E1BB\r
+S31500007890010073E304B04CE248509FE548409FE581\r
+S315000078A0B020D2E130A81B09B030D4E1013043E268\r
+S315000078B0020913E3012042E2B030C4E1B020C41152\r
+S315000078C0F030D4E18330A0E1B50093E1ADFEFFEBEB\r
+S315000078D0F030D4E18330A0E1B50093E130681BE9D4\r
+S315000078E02CFFFFEA2C17020000B102002E1702003F\r
+S315000078F00DC0A0E110D82DE904B04CE20040E0E351\r
+S31500007900241C00EB0410A0E10226A0E30A00A0E379\r
+S3150000791090FDFFEB0100A0E32A0D00EB08239FE595\r
+S315000079201700A0E30410A0E18AFDFFEBFC229FE50F\r
+S315000079300000A0E30410A0E186FDFFEBF0229FE526\r
+S315000079400100A0E30410A0E182FDFFEBE4229FE525\r
+S315000079500200A0E30410A0E17EFDFFEBD8229FE524\r
+S315000079600400A0E30410A0E17AFDFFEBCC229FE522\r
+S315000079700500A0E30410A0E176FDFFEBC0229FE521\r
+S315000079800600A0E30410A0E172FDFFEBB4229FE520\r
+S315000079900700A0E30410A0E16EFDFFEBA8229FE51F\r
+S315000079A00800A0E30410A0E16AFDFFEB9C229FE51E\r
+S315000079B00900A0E30410A0E166FDFFEB90229FE51D\r
+S315000079C01100A0E30410A0E162FDFFEB84229FE515\r
+S315000079D01200A0E30410A0E15EFDFFEB0D00A0E3A2\r
+S315000079E00410A0E10623A0E35AFDFFEB0E00A0E37E\r
+S315000079F00410A0E17524A0E356FDFFEB58229FE595\r
+S31500007A000A00A0E30410A0E152FDFFEB0B00A0E387\r
+S31500007A100410A0E10124A0E34EFDFFEB0C00A0E35F\r
+S31500007A200410A0E1722CA0E34AFDFFEB0F00A0E3D7\r
+S31500007A300410A0E1332AA0E346FDFFEB0D00A0E30E\r
+S31500007A40021AA0E30120A0E342FDFFEB0410A0E12F\r
+S31500007A501E00A0E33F20A0E33EFDFFEB0114A0E3E0\r
+S31500007A600120A0E31700A0E33AFDFFEB0300A0E32B\r
+S31500007A70D40C00EB1700A0E30118A0E30120A0E35B\r
+S31500007A8034FDFFEB1100A0E30119A0E30020A0E301\r
+S31500007A9030FDFFEB0713A0E30120A0E30600A0E3FF\r
+S31500007AA02CFDFFEB0A00A0E3C60C00EB1A00A0E3D6\r
+S31500007AB07F10A0E35AFDFFEB630050E30200009A3B\r
+S31500007AC0640050E35400000A5300008A0713A0E341\r
+S31500007AD00520A0E30600A0E31EFDFFEB0A00A0E3DD\r
+S31500007AE0B80C00EB1A00A0E37F10A0E34CFDFFEBFF\r
+S31500007AF0630050E30200009A640050E34600000A67\r
+S31500007B004500008A0400A0E30C10A0E30220A0E3D5\r
+S31500007B1010FDFFEB1D00A0E3FF14A0E340FDFFEB0B\r
+S31500007B20180050E33800009A190050E33600000AA6\r
+S31500007B301D00A0E3FF14A0E339FDFFEBE60050E3D0\r
+S31500007B400200009AE70050E32F00000A2E00008A88\r
+S31500007B5008419FE50219A0E30120A0E30200A0E38B\r
+S31500007B60FCFCFFEB0500A0E3960C00EBF0209FE584\r
+S31500007B700410A0E10200A0E3F6FCFFEB0300A0E383\r
+S31500007B80900C00EBDC209FE50410A0E10200A0E3CE\r
+S31500007B90F0FCFFEB0300A0E38A0C00EBC8209FE596\r
+S31500007BA00410A0E10200A0E3EAFCFFEB0400A0E35E\r
+S31500007BB0840C00EBB4209FE50410A0E10200A0E3D2\r
+S31500007BC0E4FCFFEB0A00A0E37E0C00EBA0209FE59F\r
+S31500007BD00410A0E10200A0E3DEFCFFEB1900A0E325\r
+S31500007BE0780C00EB8C209FE50410A0E10200A0E3D6\r
+S31500007BF0D8FCFFEB0110A0E31700A0E30120A0E1F1\r
+S31500007C00D4FCFFEB561D00EB10A81BE90200A0E315\r
+S31500007C100219A0E30020A0E3F4FFFFEA0400A0E3BA\r
+S31500007C200C10A0E30020A0E3B8FFFFEA1002010059\r
+S31500007C30F64E040004F7111CB60100000800B89FB8\r
+S31500007C4044E406850D19001C52F05B5206D1007003\r
+S31500007C50CBC2000002DB0C00500014002D223000C5\r
+S31500007C60FFFF0000A58200009583000074840000D9\r
+S31500007C703585000032860000108800000DC0A0E1A6\r
+S31500007C8070D82DE9630050E304B04CE250D04DE2C9\r
+S31500007C900060A0E368604BE59600000A040051E32B\r
+S31500007CA001F19F97710000EA707E0000707E00006F\r
+S31500007CB0BC7C0000707E0000747E00000B0050E368\r
+S31500007CC000F19F97690000EA447D00004C7D0000AA\r
+S31500007CD0707E0000547D00005C7D0000947D0000F5\r
+S31500007CE0F87C0000D87D0000E47D0000107E0000D6\r
+S31500007CF04C7E0000707E000080429FE5001094E5F7\r
+S31500007D00000051E378229F150800001A74229FE5AF\r
+S31500007D101800A0E3DE1200EB6C329FE56C229FE5B3\r
+S31500007D20003082E50130A0E3003084E570A81BE94D\r
+S31500007D301800A0E30010A0E3D51200EB0030A0E38A\r
+S31500007D40F8FFFFEA2BFEFFEB70A81BE9AFFEFFEB87\r
+S31500007D5070A81BE9C9FEFFEB70A81BE930C29FE5BE\r
+S31500007D6000109CE5000051E30030A0130310A011A1\r
+S31500007D7020229F151800A0130200001A18229FE562\r
+S31500007D801800A0E30130A0E300308CE5C01200EB40\r
+S31500007D9070A81BE9700E00EB0A4080E2FC119FE51B\r
+S31500007DA040504BE20420A0E10500A0E10448A0E118\r
+S31500007DB0D74000EB2448A0E10520A0E10010A0E395\r
+S31500007DC01000A0E3B21200EB0410A0E10100A0E352\r
+S31500007DD01A1000EB70A81BE95F0E00EB0A4040E2A8\r
+S31500007DE0EDFFFFEAB8C19FE500109CE5000051E3F6\r
+S31500007DF00030A0130310A011A8219F152800A0137E\r
+S31500007E00E0FFFF1AA0219FE52800A0E3DCFFFFEAC0\r
+S31500007E1098319FE5001093E5000051E30500000A44\r
+S31500007E208C219FE50010A0E31800A0E3981200EB58\r
+S31500007E300A1D00EB70A81BE978219FE51800A0E356\r
+S31500007E40931200EBC61C00EB70A81BE968419FE586\r
+S31500007E50001094E5000051E360219F15B3FFFF1A5F\r
+S31500007E605C219FE51800A0E3891200EBACFFFFEA56\r
+S31500007E7070A81BE9013040E2060053E303F19F9727\r
+S31500007E80FAFFFFEA4C7D0000707E0000547D000082\r
+S31500007E90707E0000A07E0000707E0000B47E0000B0\r
+S31500007EA02D0E00EB1C119FE50A4080E240504BE28C\r
+S31500007EB0BBFFFFEA280E00EB40504BE20A4040E2CF\r
+S31500007EC00420A0E100119FE50500A0E10448A0E11F\r
+S31500007ED08F4000EB2448A0E10010A0E30520A0E1BC\r
+S31500007EE01000A0E36A1200EB0410A0E10100A0E379\r
+S31500007EF0D20F00EBDDFFFFEAD0009FE5003090E5F2\r
+S31500007F00813083E0370E53E3003080E5C0309FD5E3\r
+S31500007F10003080D5B8309FE5002090E5030052E19F\r
+S31500007F20C63043C2003080C5A8209FE5003090E5EA\r
+S31500007F309203C1E0C32FA0E1412162E0374E43E244\r
+S31500007F40021182E040504BE2014044E2813043E0BE\r
+S31500007F500500A0E180109FE5A44F84E06C4000EB93\r
+S31500007F60C440A0E10610A0E10520A0E13800A0E38E\r
+S31500007F70471200EB0400A0E102FDFFEB70A81BE92D\r
+S31500007F801C170200E8080200F80802000000406022\r
+S31500007F90241702001417020008090200180902003B\r
+S31500007FA028090200181702003409020040090200DD\r
+S31500007FB0A41C02004C0902005C0902002017020002\r
+S31500007FC06C0902008009020094090200A00902005F\r
+S31500007FD0101702003704000067666666BC080200D8\r
+S31500007FE00DC0A0E1F0D92DE904B04CE224D04DE259\r
+S31500007FF00170A0E10040A0E1C51C00EB000050E3C9\r
+S315000080000010A0E14D00000A40319FE5005093E5C5\r
+S31500008010000055E34000001A2781A0E1651B00EB34\r
+S31500008020080055E10560A0E10410A0E11000002A57\r
+S31500008030F2E0D0E018319FE5F2C0D0E0002093E5F1\r
+S315000080400C308EE0000052E3C350A0E1B250C410E1\r
+S31500008050B2E0C4000E306CE0C330A0E1016086E2FD\r
+S31500008060B230C410B2C0C400080056E1040080E279\r
+S31500008070EEFFFF3ADC309FE5003093E5000053E366\r
+S31500008080D4309F15B030C111D0309F15B230C11118\r
+S31500008090CC309FE5003093E5000053E30400001A5E\r
+S315000080A00030A0E37AFF17EEFDFFFF1A9A3F07EEB6\r
+S315000080B0F0A91BE9AC409FE50728A0E1000094E584\r
+S315000080C02228A0E10130A0E3471600EB003094E53A\r
+S315000080D00120C7E3023083E08C209FE5020053E1D4\r
+S315000080E0003084E584309F8500308485002094E547\r
+S315000080F044404BE29F2482E2032582E270109FE512\r
+S315000081000400A0E1024000EB0420A0E10010A0E37F\r
+S315000081102000A0E3DE1100EBE0FFFFEA251B00EBE9\r
+S315000081200030A0E37AFF17EEFDFFFF1A9A3F07EE35\r
+S315000081300410A0E10720A0E1791C00EBD7FFFFEABD\r
+S315000081400400A0E10720A0E1D62D00EBD3FFFFEA53\r
+S315000081502017020014170200181702000380FFFF01\r
+S31500008160FD7F00001C170200241702000000D061EA\r
+S3150000817000004060AC0902000DC0A0E110D82DE956\r
+S3150000818004B04CE214D04DE2921600EB25FBFFEB57\r
+S31500008190882100EBC31000EB0000A0E39C209FE5C4\r
+S315000081A00010A0E1BA1100EB94209FE50010A0E3B7\r
+S315000081B00800A0E3B61100EB0020A0E384109FE5C1\r
+S315000081C0020AA0E3C80F00EBA01B00EB1700A0E318\r
+S315000081D0FC0A00EB0400A0E30010A0E3170F00EB7D\r
+S315000081E0C2FDFFEB60009FE5BD1500EB01FDFFEB57\r
+S315000081F0F80A00EB7D0FA0E3F20A00EB0010E0E3C3\r
+S315000082001C00A0E386FBFFEB0028A0E12228A0E1EA\r
+S315000082101F3002E224404BE2A222A0E11223A0E199\r
+S315000082200400A0E124109FE5B93F00EB0420A0E183\r
+S315000082300010A0E33000A0E3951100EBEBFFFFEA8E\r
+S31500008240B8090200C809020044AC00007C7C0000AA\r
+S31500008250D80902000DC0A0E100D82DE904B04CE217\r
+S3150000826008D04DE20030A0E10120A0E1BE304BE194\r
+S31500008270B0214BE1FE305BE1000053E30200001A3F\r
+S315000082802C309FE514300BE5010000EA24309FE511\r
+S3150000829014300BE5FE305BE1FEC05BE118009FE5A4\r
+S315000082A014101BE50320A0E10C30A0E1772C00EBB5\r
+S315000082B000A81BE9E4090200EC090200F409020027\r
+S315000082C00DC0A0E100D82DE904B04CE228D04DE263\r
+S315000082D010000BE514100BE518200BE51C300BE520\r
+S315000082E010201BE514301BE5003082E510301BE53D\r
+S315000082F0003093E520300BE520201BE518301BE508\r
+S31500008300032022E01C301BE5033002E024300BE59D\r
+S3150000831024301BE5000053E31300000A18301BE568\r
+S3150000832000308DE51C301BE504308DE504309BE5FF\r
+S3150000833008308DE540009FE508109BE510201BE501\r
+S3150000834020301BE5512C00EB30109FE52C309FE5CB\r
+S31500008350002093E504309BE5033082E1003081E59F\r
+S315000083600130A0E328300BE5010000EA0030A0E36D\r
+S3150000837028300BE528001BE500A81BE9240A0200AB\r
+S31500008380301702000DC0A0E100D82DE904B04CE280\r
+S3150000839028D04DE210000BE514100BE518200BE574\r
+S315000083A01C300BE510301BE5003093E520300BE563\r
+S315000083B020201BE514301BE5032022E018301BE5C6\r
+S315000083C0033002E024300BE524301BE5000053E3C4\r
+S315000083D01300000A14301BE500308DE518301BE54C\r
+S315000083E004308DE51C301BE508308DE540009FE527\r
+S315000083F004109BE510201BE520301BE5232C00EB29\r
+S3150000840030109FE52C309FE5002093E51C301BE5DE\r
+S31500008410033082E1003081E50130A0E328300BE52E\r
+S31500008420010000EA0030A0E328300BE528001BE538\r
+S3150000843000A81BE9980A0200301702000DC0A0E14F\r
+S3150000844000D82DE904B04CE204D04DE210000BE553\r
+S3150000845014209FE510301BE5003082E50C209FE5D7\r
+S315000084600130A0E3003082E500A81BE938170200BE\r
+S31500008470341702000DC0A0E100D82DE904B04CE28B\r
+S3150000848008D04DE270319FE5003093E5000053E3DC\r
+S315000084900300000A60319FE5003093E510300BE5DC\r
+S315000084A0010000EA54019FE510000BE550319FE5FD\r
+S315000084B0003093E5000053E30600000A40319FE5D3\r
+S315000084C00020A0E3002083E52C319FE534019FE5E1\r
+S315000084D0001093E5ED2B00EB2C319FE510101BE50A\r
+S315000084E09123C3E04327A0E110001BE5C03FA0E1B4\r
+S315000084F0021063E00130A0E10332A0E1013083E025\r
+S315000085000331A0E1013083E08330A0E1013083E054\r
+S315000085100321A0E1023083E08331A0E1013083E052\r
+S315000085208331A0E110101BE5010063E00030A0E1FB\r
+S315000085308330A0E1003083E08321A0E1023083E0B4\r
+S315000085400332A0E1033060E08311A0E1011063E093\r
+S315000085500112A0E1011060E0AC309FE510201BE5A0\r
+S315000085609203C3E04327A0E110001BE5C03FA0E152\r
+S31500008570020063E00030A0E18330A0E1003083E038\r
+S315000085800322A0E1023083E08330A0E1003083E0E3\r
+S315000085908322A0E1023083E0011063E010100BE5B6\r
+S315000085A010101BE5000051E3020000AA10201BE595\r
+S315000085B0062142E210200BE510301BE50231C3E331\r
+S315000085C010300BE510001BE5000050E30200000A26\r
+S315000085D010101BE514100BE5010000EA1C209FE5B6\r
+S315000085E014200BE514001BE50C309FE5000083E525\r
+S315000085F010301BE50300A0E100A81BE938170200B4\r
+S3150000860024D95B0734170200080B0200C989475EAC\r
+S315000086100DC0A0E100D82DE904B04CE21CD04DE21B\r
+S3150000862010000BE514100BE518200BE510301BE5C8\r
+S31500008630000053E3030000BA10301BE53F0053E38C\r
+S31500008640000000CA020000EA0130A0E31C300BE57E\r
+S31500008650250000EA98309FE510201BE5023193E7DC\r
+S31500008660000053E30200000A0230A0E31C300BE5D1\r
+S315000086701D0000EA78109FE510201BE514301BE56D\r
+S31500008680023181E70030A0E300308DE510301BE5B4\r
+S315000086900321A0E15C309FE5023083E004308DE5E4\r
+S315000086A010201BE50230A0E18331A0E1033062E037\r
+S315000086B00321A0E140309FE5023083E008308DE5DC\r
+S315000086C010001BE50010A0E318201BE514301BE585\r
+S315000086D0EE2D00EB1C209FE510301BE5030192E711\r
+S315000086E0FF2D00EB0030A0E31C300BE51C001BE562\r
+S315000086F000A81BE970350200903D020074360200A6\r
+S315000087000DC0A0E100D82DE904B04CE208D04DE23E\r
+S3150000871010000BE510301BE5000053E3030000BA20\r
+S3150000872010301BE53F0053E3000000CA020000EAD8\r
+S315000087300130A0E314300BE50D0000EA38109FE588\r
+S3150000874010201BE50030A0E3023181E72C209FE5D5\r
+S3150000875010301BE5030192E7E42D00EB1C209FE59A\r
+S3150000876010301BE5030192E7DA2D00EB0030A0E3A1\r
+S3150000877014300BE514001BE500A81BE97035020058\r
+S31500008780903D02000DC0A0E100D82DE904B04CE2F6\r
+S315000087901CD04DE210000BE514100BE54030A0E3B1\r
+S315000087A018300BE5D4309FE5003093E5000053E325\r
+S315000087B00200000A0230A0E31C300BE52D0000EA9F\r
+S315000087C0B8209FE510301BE5003082E50030A0E3BD\r
+S315000087D000308DE518301BE50321A0E1A0309FE5B0\r
+S315000087E0023083E004308DE518201BE50230A0E15D\r
+S315000087F08331A0E1033062E00321A0E184309FE5EC\r
+S31500008800023083E008308DE518001BE50010A0E378\r
+S3150000881014201BE510301BE59C2D00EB68209FE51E\r
+S3150000882018301BE5032192E760309FE5030052E113\r
+S315000088300E00001A50109FE518201BE510301BE5AE\r
+S31500008840023181E748109FE518201BE514301BE52F\r
+S31500008850023181E73C009FE518101BE518301BE547\r
+S315000088600321A0E118309FE5023083E0013180E763\r
+S315000088700030A0E31C300BE51C001BE500A81BE93B\r
+S3150000888070360200903D02007436020004140200A5\r
+S31500008890A8210100081502000C1602000DC0A0E177\r
+S315000088A000D82DE904B04CE204D04DE24030A0E3FC\r
+S315000088B010300BE564209FE50030A0E3003082E530\r
+S315000088C05C009FE510101BE558209FE510301BE566\r
+S315000088D0033192E7012190E7083093E5030052E166\r
+S315000088E00B00001A38109FE510201BE538309FE575\r
+S315000088F0023181E734109FE510201BE50030A0E32C\r
+S31500008900023181E728109FE510201BE50030A0E327\r
+S31500008910023181E70030A0E30300A0E100A81BE9D3\r
+S315000089207036020004140200903D0200A8210100E6\r
+S31500008930081502000C1602000DC0A0E100D82DE9B2\r
+S3150000894004B04CE218D04DE210000BE514100BE514\r
+S3150000895018200BE51C300BE510301BE5000053E337\r
+S31500008960030000BA10301BE53F0053E3000000CAC5\r
+S31500008970020000EA0130A0E324300BE5230000EA00\r
+S3150000898010201BE5C23FA0E1233FA0E1033082E0B7\r
+S315000089904321A0E10231A0E3603083E2023293E793\r
+S315000089A020300BE510201BE5C23FA0E1233FA0E1EC\r
+S315000089B0033082E04331A0E10331A0E1023063E0FD\r
+S315000089C08321A0E120301BE53332A0E120300BE506\r
+S315000089D014201BE520301BE52331A0E1013003E222\r
+S315000089E0003082E518201BE520301BE5A331A0E10D\r
+S315000089F0013003E2003082E51C201BE520301BE538\r
+S31500008A00033003E2003082E50030A0E324300BE5BA\r
+S31500008A1024001BE500A81BE90DC0A0E100D82DE944\r
+S31500008A2004B04CE20CD04DE210000BE50B30E0E355\r
+S31500008A300C004BE2033080E0060083E810201BE5C3\r
+S31500008A400030A0E3003082E510201BE50030A0E3F3\r
+S31500008A500430C2E510201BE50739A0E3823183E22A\r
+S31500008A60003093E5083082E510201BE510301BE549\r
+S31500008A70083093E50C3082E510201BE51030A0E3AA\r
+S31500008A80033082E00020A0E30010A0E3060083E8A4\r
+S31500008A9010201BE51830A0E3032082E00B30E0E352\r
+S31500008AA00C004BE2033080E0030093E8030082E809\r
+S31500008AB010201BE50030A0E32030C2E500A81BE92A\r
+S31500008AC00DC0A0E110D82DE904B04CE20CD04DE267\r
+S31500008AD014000BE514201BE50739A0E3823183E27D\r
+S31500008AE0003093E50C3082E514301BE514201BE5BD\r
+S31500008AF00C1093E5083092E5030051E11700002AB7\r
+S31500008B0014201BE50130A0E30430C2E514201BE568\r
+S31500008B101030A0E303C082E014301BE5003093E57B\r
+S31500008B200310A0E10020A0E30140A0E10030A0E393\r
+S31500008B3014201BE514101BE50C0092E5082091E5B6\r
+S31500008B40002062E0012042E20210A0E10020A0E342\r
+S31500008B50013083E1024084E118008CE8240000EA39\r
+S31500008B6014301BE514201BE50C1093E5083092E544\r
+S31500008B70030051E11E00003A14301BE50430D3E532\r
+S31500008B80010053E30700001A14201BE514301BE50F\r
+S31500008B90003093E5013083E2003082E514201BE5C6\r
+S31500008BA00030A0E30430C2E514201BE51030A0E33A\r
+S31500008BB003C082E014301BE5003093E50310A0E10A\r
+S31500008BC00020A0E30140A0E10030A0E314201BE553\r
+S31500008BD014101BE50C0092E5082091E5002062E0E8\r
+S31500008BE00210A0E10020A0E3013083E1024084E10D\r
+S31500008BF018008CE814201BE51830A0E3032082E05F\r
+S31500008C0018200BE514201BE51030A0E3032082E0BA\r
+S31500008C101C200BE518101BE5042091E51C101BE534\r
+S31500008C20043091E5030052E10E00008A18301BE57E\r
+S31500008C30042093E51C101BE5043091E5030052E186\r
+S31500008C400500001A18301BE5002093E51C101BE5F3\r
+S31500008C50003091E5030052E10200008A14301BE562\r
+S31500008C600120A0E32020C3E514301BE52030D3E526\r
+S31500008C700300A0E110A81BE90DC0A0E100D82DE972\r
+S31500008C8004B04CE22CD04DE210304BE2030003E876\r
+S31500008C9038304BE20300A0E110304BE2060013E847\r
+S31500008CA05CFFFFEB38304BE20300A0E183FFFFEBF4\r
+S31500008CB00030A0E1FF3003E2000053E3F8FFFF0AB3\r
+S31500008CC000A81BE90DC0A0E100D82DE904B04CE2D4\r
+S31500008CD004D04DE210000BE510301BE5050053E310\r
+S31500008CE00100008A04009FE5E82900EB00A81BE9C3\r
+S31500008CF0480B02000DC0A0E100D82DE904B04CE2FB\r
+S31500008D0004D04DE210000BE510301BE5050053E3DF\r
+S31500008D100100008A04009FE5DC2900EB00A81BE99E\r
+S31500008D20900B02000DC0A0E100D82DE904B04CE282\r
+S31500008D3004D04DE210000BE510301BE5050053E3AF\r
+S31500008D400100008A04009FE5D02900EB00A81BE97A\r
+S31500008D50E40B02000DC0A0E100D82DE904B04CE2FE\r
+S31500008D6030D04DE20231A0E3013783E2003093E5D3\r
+S31500008D7010300BE58231A0E3013783E2003093E542\r
+S31500008D8014300BE5C231A0E3013783E2003093E5EE\r
+S31500008D9018300BE50231A0E3013783E2403083E26D\r
+S31500008DA0003093E51C300BE50231A0E3013783E286\r
+S31500008DB0803083E2003093E520300BE50231A0E3FA\r
+S31500008DC0013783E2903083E2003093E524300BE5EF\r
+S31500008DD00231A0E3013783E2A03083E2003093E55D\r
+S31500008DE028300BE50231A0E3013783E2B03083E29D\r
+S31500008DF0003093E52C300BE50231A0E3013783E226\r
+S31500008E00C03083E2003093E530300BE50231A0E359\r
+S31500008E10013783E2703083E2003093E534300BE5AE\r
+S31500008E200E305BE5013003E2000053E30400000A64\r
+S31500008E30B0315BE1833BA0E1A33BA0E1B6334BE15C\r
+S31500008E40010000EA0030A0E3B6334BE1B6335BE144\r
+S31500008E50B4229FE5B030C2E1AC229FE513305BE55A\r
+S31500008E602332A0E1FF3003E2013003E20230C2E523\r
+S31500008E7016305BE52332A0E1FF3003E2013003E266\r
+S31500008E80000053E31800000A16305BE5033003E2E6\r
+S31500008E90030053E303F19F97160000EAAC8E00002F\r
+S31500008EA0BC8E0000CC8E0000DC8E000058329FE5A0\r
+S31500008EB00120A0E30320C3E50E0000EA48329FE547\r
+S31500008EC00220A0E30320C3E50A0000EA38329FE54A\r
+S31500008ED00420A0E30320C3E5060000EA28329FE54C\r
+S31500008EE00820A0E30320C3E5020000EA18329FE54C\r
+S31500008EF00020A0E30320C3E50C229FE5B4315BE12B\r
+S31500008F00033BA0E1233BA0E1B430C2E1F8219FE599\r
+S31500008F1018305BE51F3003E20630C2E5E8219FE525\r
+S31500008F20BC315BE1033BA0E1233BA0E1B231C2E1EE\r
+S31500008F3021305BE5A333A0E1FF3003E2000053E3F9\r
+S31500008F400400001AB4325BE1033BA0E1233BA0E13D\r
+S31500008F50B8334BE1010000EA0030A0E3B8334BE13F\r
+S31500008F60B8335BE1A0219FE5B830C2E11D305BE577\r
+S31500008F70A333A0E1FF3003E2000053E30400001A2C\r
+S31500008F80B0325BE1833BA0E1A33BA0E1BA334BE106\r
+S31500008F90010000EA0030A0E3BA334BE1BA335BE1EB\r
+S31500008FA064219FE5BA30C2E12D305BE5A333A0E131\r
+S31500008FB0FF3003E2000053E30600000A48219FE564\r
+S31500008FC00030A0E3BC30C2E13C219FE50030A0E3C5\r
+S31500008FD0BE30C2E1160000EA2D305BE5A332A0E107\r
+S31500008FE0FF3003E2013003E2000053E30600000A0B\r
+S31500008FF014219FE50030A0E3BC30C2E108219FE5C3\r
+S315000090000130A0E3BE30C2E1090000EAF8209FE586\r
+S31500009010BE325BE1833BA0E1A33BA0E1BC30C2E1F1\r
+S31500009020E4209FE5B0335BE1033BA0E1233BA0E1F5\r
+S31500009030BE30C2E129305BE5A333A0E1FF3003E295\r
+S31500009040000053E30300001A2C305BE5073003E20F\r
+S315000090503B304BE5010000EA0030A0E33B304BE536\r
+S315000090603B305BE5A0209FE50730C2E50030A0E37A\r
+S3150000907094209FE51130C2E50E305BE52331A0E177\r
+S31500009080FF3003E2013003E2000053E30D00000A63\r
+S3150000909031305BE5A333A0E1FF3003E2000053E388\r
+S315000090A00800001A31305BE52333A0E1FF3003E20C\r
+S315000090B0013003E2000053E30200001A0130A0E38E\r
+S315000090C044209FE51130C2E525305BE5A333A0E1DE\r
+S315000090D0FF3003E2000053E30300001A28305BE58B\r
+S315000090E0073003E23C304BE5010000EA0030A0E324\r
+S315000090F03C304BE53C205BE50C309FE51020C3E59A\r
+S315000091000030A0E30300A0E100A81BE9943E0200A2\r
+S315000091100DC0A0E100D82DE904B04CE208D04DE224\r
+S3150000912010000BE50030A0E314300BE514301BE50E\r
+S31500009130040053E30000009A090000EA10001BE552\r
+S3150000914014101BE524209FE514301BE5033192E73C\r
+S31500009150013180E714301BE5013083E214300BE562\r
+S31500009160F1FFFFEA0030A0E30300A0E100A81BE93D\r
+S31500009170943E02000DC0A0E100D82DE904B04CE2F7\r
+S315000091801CD04DE210000BE5D0319FE5B030D3E1A5\r
+S3150000919014300BE510301BE5B030D3E118300BE589\r
+S315000091A00030A0E31C300BE518301BE5000053E34C\r
+S315000091B00400000A14301BE5000053E30100001A06\r
+S315000091C00130A0E31C300BE50030A0E320300BE5B6\r
+S315000091D018301BE5000053E30400001A14301BE5A9\r
+S315000091E0000053E30100000A0130A0E320300BE544\r
+S315000091F018201BE514301BE5030052E10030A09354\r
+S315000092000130A08324300BE518201BE514301BE544\r
+S31500009210030052E10030A0230130A03328300BE5D3\r
+S315000092201C301BE5000053E30200000A10001BE59A\r
+S31500009230FE0000EB400000EA20301BE5000053E38F\r
+S315000092400200000A10001BE53B0100EB3A0000EAB1\r
+S3150000925024301BE5000053E30200000A10001BE562\r
+S31500009260770100EB340000EA28301BE5000053E3E9\r
+S315000092700200000A10001BE5AC0100EB2E0000EA1C\r
+S3150000928010301BE5B231D3E10300A0E1EC0300EBA3\r
+S3150000929010301BE5BC20D3E110301BE5BE30D3E116\r
+S315000092A00200A0E10310A0E10020A0E3580200EBB9\r
+S315000092B010301BE51030D3E50300A0E1320200EBCD\r
+S315000092C010301BE5BA30D3E10300A0E10010A0E3A3\r
+S315000092D0A10200EB10301BE5B830D3E10300A0E19A\r
+S315000092E00010A0E3D20200EB10301BE50730D3E5F7\r
+S315000092F00300A0E10010A0E3030300EB10301BE520\r
+S315000093000620D3E510301BE50330D3E50200A0E1CB\r
+S315000093100310A0E10020A0E3300300EB10301BE5B2\r
+S31500009320B420D3E110301BE50230D3E50200A0E102\r
+S315000093300310A0E10020A0E3870300EB10301BE53B\r
+S315000093401130D3E518001BE514101BE50320A0E13E\r
+S31500009350E90300EB0030A0E30300A0E100A81BE94D\r
+S31500009360943E02000DC0A0E100D82DE904B04CE205\r
+S3150000937008D04DE210000BE514100BE514301BE588\r
+S31500009380B030D3E1000053E30800000A10301BE5BB\r
+S31500009390050053E30A00008A14301BE5B030D3E120\r
+S315000093A040029FE50310A0E1382800EB040000EA24\r
+S315000093B010301BE5050053E30100008A28029FE5F3\r
+S315000093C0322800EB10301BE5050053E30400008A49\r
+S315000093D014301BE5B430D3E110029FE50310A0E181\r
+S315000093E02A2800EB10301BE5050053E30400008A31\r
+S315000093F014301BE50630D3E5F4019FE50310A0E128\r
+S31500009400222800EB10301BE5050053E30400008A18\r
+S3150000941014301BE5B231D3E1D8019FE50310A0E17A\r
+S315000094201A2800EB14301BE50730D3E5000053E3A0\r
+S315000094300800000A10301BE5050053E30A00008A05\r
+S3150000944014301BE50730D3E5AC019FE50310A0E11E\r
+S315000094500E2800EB040000EA10301BE5050053E37C\r
+S315000094600100008A94019FE5082800EB14301BE5F3\r
+S31500009470B830D3E1000053E30800000A10301BE5C2\r
+S31500009480050053E30A00008A14301BE5B830D3E127\r
+S315000094906C019FE50310A0E1FC2700EB040000EA45\r
+S315000094A010301BE5050053E30100008A54019FE5D7\r
+S315000094B0F62700EB14301BE5BA30D3E1000053E386\r
+S315000094C00800000A10301BE5050053E30A00008A75\r
+S315000094D014301BE5BA30D3E12C019FE50310A0E15F\r
+S315000094E0EA2700EB040000EA10301BE5050053E311\r
+S315000094F00100008A14019FE5E42700EB14301BE508\r
+S315000095001030D3E5000053E30800000A10301BE5D5\r
+S31500009510050053E30A00008A14301BE51030D3E53A\r
+S31500009520EC009FE50310A0E1D82700EB040000EA59\r
+S3150000953010301BE5050053E30100008AD4009FE5C7\r
+S31500009540D22700EB10301BE5050053E30400008A28\r
+S3150000955014301BE5BC30D3E1BC009FE50310A0E14D\r
+S31500009560CA2700EB10301BE5050053E30400008A10\r
+S3150000957014301BE5BE30D3E1A0009FE50310A0E147\r
+S31500009580C22700EB10301BE5050053E30400008AF8\r
+S3150000959014301BE51130D3E584009FE50310A0E1EC\r
+S315000095A0BA2700EB10301BE5050053E30400008AE0\r
+S315000095B014301BE50330D3E568009FE50310A0E1F6\r
+S315000095C0B22700EB10301BE5050053E30400008AC8\r
+S315000095D014301BE50230D3E54C009FE50310A0E1F3\r
+S315000095E0AA2700EB00A81BE9540C0200640C020039\r
+S315000095F0740C0200880C02009C0C0200B00C0200E5\r
+S31500009600C40C0200D80C0200EC0C0200000D020093\r
+S31500009610140D0200280D02003C0D0200500D020040\r
+S31500009620600D0200700D0200840D0200A00D020004\r
+S315000096300DC0A0E100D82DE904B04CE204D04DE203\r
+S3150000964010000BE510301BE5B030D3E10300A0E1BC\r
+S31500009650190100EBF00000EBF000A0E3F80200EBCC\r
+S3150000966010301BE5B420D3E110301BE50230D3E502\r
+S315000096700200A0E10310A0E10020A0E3B60200EB87\r
+S3150000968010301BE50620D3E510301BE50330D3E58B\r
+S315000096900200A0E10310A0E10020A0E34F0200EBCE\r
+S315000096A010301BE50730D3E50300A0E10010A0E36E\r
+S315000096B0150200EB10301BE5BC20D3E110301BE592\r
+S315000096C0BE30D3E10200A0E10310A0E10020A0E338\r
+S315000096D04F0100EB10301BE51030D3E50300A0E18D\r
+S315000096E0290100EB10301BE5BA30D3E10300A0E1FD\r
+S315000096F00010A0E3980100EB10301BE5B830D3E171\r
+S315000097000300A0E10010A0E3C90100EBD10000EBCB\r
+S315000097102231A0E3013783E20228A0E3002083E59B\r
+S3150000972010301BE5B231D3E10300A0E1C40200EB27\r
+S315000097300030A0E30300A0E100A81BE90DC0A0E1F2\r
+S3150000974000D82DE904B04CE204D04DE210000BE540\r
+S31500009750F000A0E3BA0200EB1231A0E3013783E286\r
+S315000097600228A0E3002083E510301BE5B030D3E1EA\r
+S315000097700300A0E1D00000EB10301BE5B420D3E1DC\r
+S3150000978010301BE50230D3E50200A0E10310A0E192\r
+S315000097900020A0E3700200EB10301BE50620D3E5A5\r
+S315000097A010301BE50330D3E50200A0E10310A0E171\r
+S315000097B00020A0E3090200EBA60000EB10301BE539\r
+S315000097C0B231D3E10300A0E19D0200EB10301BE5AE\r
+S315000097D0BC20D3E110301BE5BE30D3E10200A0E18E\r
+S315000097E00310A0E10020A0E3090100EB10301BE507\r
+S315000097F01030D3E50300A0E1E30000EB10301BE5D9\r
+S31500009800BA30D3E10300A0E10010A0E3520100EB5F\r
+S3150000981010301BE5B830D3E10300A0E10010A0E34F\r
+S31500009820830100EB10301BE50730D3E50300A0E110\r
+S315000098300010A0E3B40100EB0030A0E30300A0E1B8\r
+S3150000984000A81BE90DC0A0E100D82DE904B04CE248\r
+S3150000985004D04DE210000BE510301BE5B231D3E128\r
+S315000098600300A0E1760200EB10301BE5B420D3E143\r
+S3150000987010301BE50230D3E50200A0E10310A0E1A1\r
+S315000098800020A0E3340200EB10301BE50620D3E5F0\r
+S3150000989010301BE50330D3E50200A0E10310A0E180\r
+S315000098A00020A0E3CD0100EB10301BE50730D3E527\r
+S315000098B00300A0E10010A0E3930100EB10301BE5CC\r
+S315000098C0BC20D3E110301BE5BE30D3E10200A0E19D\r
+S315000098D00310A0E10020A0E3CD0000EB10301BE553\r
+S315000098E01030D3E50300A0E1A70000EB10301BE524\r
+S315000098F0BA30D3E10300A0E10010A0E3160100EBAB\r
+S3150000990010301BE5B830D3E10300A0E10010A0E35E\r
+S31500009910470100EB10301BE5B030D3E10300A0E1B6\r
+S31500009920650000EB0030A0E30300A0E100A81BE9FE\r
+S315000099300DC0A0E100D82DE904B04CE204D04DE200\r
+S3150000994010000BE510301BE5B231D3E10300A0E1B6\r
+S315000099503B0200EB10301BE5B420D3E110301BE5D1\r
+S315000099600230D3E50200A0E10310A0E10120A0E34C\r
+S31500009970F90100EB10301BE50620D3E510301BE59E\r
+S315000099800330D3E50200A0E10310A0E10120A0E32B\r
+S31500009990920100EB10301BE50730D3E50300A0E190\r
+S315000099A00110A0E3580100EB10301BE5BC20D3E109\r
+S315000099B010301BE5BE30D3E10200A0E10310A0E1A8\r
+S315000099C00120A0E3920000EB10301BE51030D3E538\r
+S315000099D00300A0E16C0000EB10301BE5BA30D3E1C8\r
+S315000099E00300A0E10110A0E3DB0000EB10301BE553\r
+S315000099F0B830D3E10300A0E10110A0E30C0100EBB5\r
+S31500009A0010301BE5B030D3E10300A0E12A0000EBE3\r
+S31500009A100030A0E30300A0E100A81BE90DC0A0E10F\r
+S31500009A2000D82DE904B04CE20000A0E14231A0E3E9\r
+S31500009A30013783E20330D3E5FF3003E2A333A0E12D\r
+S31500009A40FF3003E2000053E3F7FFFF0A0030A0E314\r
+S31500009A500300A0E100A81BE90DC0A0E100D82DE994\r
+S31500009A6004B04CE20000A0E18231A0E3013783E2BA\r
+S31500009A700330D3E5FF3003E2A332A0E1FF3003E277\r
+S31500009A80013003E2000053E3F6FFFF1AC231A0E300\r
+S31500009A90013783E20330D3E5FF3003E2A332A0E1CE\r
+S31500009AA0FF3003E2013003E2000053E3EDFFFF1A4B\r
+S31500009AB00030A0E30300A0E100A81BE90DC0A0E16F\r
+S31500009AC000D82DE904B04CE20CD04DE210000BE5B5\r
+S31500009AD010301BE5000053E31900000A0231A0E331\r
+S31500009AE0013783E2003093E514300BE514101BE5D3\r
+S31500009AF018100BE510301BE5832BA0E118101BE5B1\r
+S31500009B00A134A0E1023083E1E33BA0E118300BE58C\r
+S31500009B1018301BE514300BE512305BE5013083E3AA\r
+S31500009B2012304BE50231A0E3013783E214201BE536\r
+S31500009B30002083E54C209FE5B0315BE1B030C2E107\r
+S31500009B400D0000EA0231A0E3013783E2003093E51D\r
+S31500009B5014300BE512305BE50130C3E312304BE500\r
+S31500009B600231A0E3013783E214201BE5002083E5E0\r
+S31500009B7010209FE50030A0E3B030C2E10030A0E342\r
+S31500009B800300A0E100A81BE9943E02000DC0A0E17D\r
+S31500009B9000D82DE904B04CE208D04DE210000BE5E8\r
+S31500009BA068309FE51030D3E514300BE510201BE537\r
+S31500009BB014301BE5030052E11100000A10301BE5CA\r
+S31500009BC0000053E30600000A0231A0E3013783E2F6\r
+S31500009BD0A03083E210201BE5072002E2002083E587\r
+S31500009BE0040000EA0231A0E3013783E2A03083E2F9\r
+S31500009BF00221A0E3002083E510209FE510305BE5FD\r
+S31500009C001030C2E50030A0E30300A0E100A81BE984\r
+S31500009C10943E02000DC0A0E100D82DE904B04CE24C\r
+S31500009C2014D04DE210000BE514100BE518200BE5DF\r
+S31500009C3020319FE5BC30D3E11C300BE514319FE5A4\r
+S31500009C40BE30D3E120300BE510201BE51C301BE5B0\r
+S31500009C50030052E10400001A14201BE520301BE526\r
+S31500009C60030052E10000001A370000EA10301BE53D\r
+S31500009C70000053E30800001A14301BE5000053E30C\r
+S31500009C800500001A0231A0E3013783E2803083E247\r
+S31500009C900221A0E3002083E5250000EA10301BE541\r
+S31500009CA0030053E31A00009A10301BE5820053E3C9\r
+S31500009CB01700008A14301BE5040053E31400009AD1\r
+S31500009CC014301BE5030C53E31100008A0221A0E3C4\r
+S31500009CD0012782E2802082E218301BE5033FA0E1E3\r
+S31500009CE0011103E210301BE50338A0E1FE34C3E3A3\r
+S31500009CF02338A0E10338A0E1031081E114301BE50D\r
+S31500009D00033BA0E1233BA0E1033081E1003082E583\r
+S31500009D10070000EA0221A0E3012782E2802082E216\r
+S31500009D2018301BE5033FA0E1013103E2023283E371\r
+S31500009D30003082E51C209FE5B0315BE1BC30C2E11A\r
+S31500009D4010209FE5B4315BE1BE30C2E10030A0E3F4\r
+S31500009D500300A0E100A81BE9943E02000DC0A0E1AB\r
+S31500009D6000D82DE904B04CE214D04DE210000BE50A\r
+S31500009D7014100BE5B4309FE5BA30D3E118300BE58B\r
+S31500009D8010201BE518301BE5030052E12400000AF1\r
+S31500009D9010301BE5000053E31900000A14301BE5E0\r
+S31500009DA0000053E30600000A18201BE510301BE5EF\r
+S31500009DB0030052E10030A0930130A08320300BE570\r
+S31500009DC0010000EA0030A0E320300BE520301BE55F\r
+S31500009DD01C300BE50221A0E3012782E2802082E20B\r
+S31500009DE01C301BE5033FA0E1011103E210301BE527\r
+S31500009DF0833BA0E1A33BA0E1033081E1003082E593\r
+S31500009E00040000EA0231A0E3013783E2803083E2F6\r
+S31500009E100221A0E3002083E510209FE5B0315BE13D\r
+S31500009E20BA30C2E10030A0E30300A0E100A81BE9BC\r
+S31500009E30943E02000DC0A0E100D82DE904B04CE22A\r
+S31500009E4014D04DE210000BE514100BE5B4309FE57D\r
+S31500009E50B830D3E118300BE510201BE518301BE5B0\r
+S31500009E60030052E12400000A10301BE5000053E312\r
+S31500009E701900000A14301BE5000053E30600000A2F\r
+S31500009E8018201BE510301BE5030052E10030A093BB\r
+S31500009E900130A08320300BE5010000EA0030A0E38A\r
+S31500009EA020300BE520301BE51C300BE50221A0E33A\r
+S31500009EB0012782E2902082E21C301BE5033FA0E1ED\r
+S31500009EC0011103E210301BE5033BA0E1233BA0E1B7\r
+S31500009ED0033081E1003082E5040000EA0231A0E3AC\r
+S31500009EE0013783E2903083E20221A0E3002083E57C\r
+S31500009EF010209FE5B0315BE1B830C2E10030A0E34D\r
+S31500009F000300A0E100A81BE9943E02000DC0A0E1F9\r
+S31500009F1000D82DE904B04CE214D04DE210000BE558\r
+S31500009F2014100BE5B0309FE50730D3E518300BE58C\r
+S31500009F3010201BE518301BE5030052E12300000A40\r
+S31500009F4010301BE5000053E31800000A14301BE52F\r
+S31500009F50000053E30600000A18201BE510301BE53D\r
+S31500009F60030052E10030A0930130A08320300BE5BE\r
+S31500009F70010000EA0030A0E320300BE520301BE5AD\r
+S31500009F801C300BE50221A0E3012782E2B02082E229\r
+S31500009F901C301BE5033FA0E1011103E210301BE575\r
+S31500009FA0073003E2033081E1003082E5040000EA75\r
+S31500009FB00231A0E3013783E2B03083E20221A0E35D\r
+S31500009FC0002083E510209FE510305BE50730C2E5F1\r
+S31500009FD00030A0E30300A0E100A81BE9943E0200C4\r
+S31500009FE00DC0A0E100D82DE904B04CE224D04DE22A\r
+S31500009FF010000BE514100BE518200BE554319FE516\r
+S3150000A0000630D3E51C300BE510201BE51C301BE5A4\r
+S3150000A010030052E10500001A38319FE50320D3E51D\r
+S3150000A02014301BE5020053E10000001A460000EA66\r
+S3150000A03018301BE5000053E30600000A1C201BE550\r
+S3150000A04010301BE5030052E10030A0930130A083DD\r
+S3150000A0502C300BE5010000EA0030A0E32C300BE5C4\r
+S3150000A0602C301BE520300BE514301BE5000053E3D4\r
+S3150000A0700030A0030130A01324300BE514301BE59B\r
+S3150000A080010053E31400000A14301BE5020053E3F9\r
+S3150000A0900E00000A14301BE5040053E30800000A12\r
+S3150000A0A014301BE5080053E30200001A0330A0E356\r
+S3150000A0B030300BE50A0000EA0030E0E330300BE513\r
+S3150000A0C0070000EA0230A0E330300BE5040000EAA6\r
+S3150000A0D00130A0E330300BE5010000EA0030A0E3D8\r
+S3150000A0E030300BE530301BE528300BE5C211A0E31C\r
+S3150000A0F0011781E220301BE5033FA0E1012103E2C5\r
+S3150000A10024301BE5033AA0E1013603E2032082E195\r
+S3150000A11028301BE50338A0E1033803E2032082E17F\r
+S3150000A12010301BE51F3003E2033082E1F63683E38D\r
+S3150000A130003081E51C209FE510305BE50630C2E566\r
+S3150000A14010209FE514305BE50330C2E50030A0E344\r
+S3150000A1500300A0E100A81BE9943E02000DC0A0E1A7\r
+S3150000A16000D82DE904B04CE218D04DE210000BE502\r
+S3150000A17014100BE518200BE5C0309FE5B430D3E191\r
+S3150000A1801C300BE510201BE51C301BE5030052E1DB\r
+S3150000A1900500001AA4309FE50220D3E514301BE524\r
+S3150000A1A0020053E10000001A210000EA18301BE506\r
+S3150000A1B0000053E30600000A1C201BE510301BE5D7\r
+S3150000A1C0030052E10030A0930130A08324300BE558\r
+S3150000A1D0010000EA0030A0E324300BE524301BE543\r
+S3150000A1E020300BE58221A0E3012782E220301BE527\r
+S3150000A1F0033FA0E1011103E214301BE50336A0E1A1\r
+S3150000A200013A03E2031081E110301BE5033BA0E1B4\r
+S3150000A210233BA0E1033081E1003082E51C209FE56D\r
+S3150000A220B0315BE1B430C2E110209FE514305BE54C\r
+S3150000A2300230C2E50030A0E30300A0E100A81BE95C\r
+S3150000A240943E02000DC0A0E100D82DE904B04CE216\r
+S3150000A25008D04DE210000BE598309FE5B231D3E10E\r
+S3150000A26014300BE510201BE514301BE5030052E10A\r
+S3150000A2701D00000A0221A0E3012782E2402082E2BB\r
+S3150000A2800231A0E3013783E2403083E2003093E5F8\r
+S3150000A290FF3FC3E30330C3E3003082E50221A0E3BE\r
+S3150000A2A0012782E2402082E210301BE5031BA0E179\r
+S3150000A2B0211BA0E110301BE5033BA0E1233BA0E1FD\r
+S3150000A2C00300E0E10231A0E3013783E2403083E29C\r
+S3150000A2D0003093E5033000E0033081E1003082E591\r
+S3150000A2E010209FE5B0315BE1B231C2E10030A0E35E\r
+S3150000A2F00300A0E100A81BE9943E02000DC0A0E106\r
+S3150000A30000D82DE904B04CE20CD04DE210000BE56C\r
+S3150000A31014100BE518200BE5B0309FE51120D3E5AE\r
+S3150000A32018301BE5020053E10400001A10201BE55B\r
+S3150000A33014301BE5030052E10000001A200000EA79\r
+S3150000A34018301BE5000053E31100000A10301BE52E\r
+S3150000A3501E0E53E30E00001A10201BE514301BE5F9\r
+S3150000A360030052E10000000AABFDFFEB1231A0E34F\r
+S3150000A370013783E20127A0E3002083E50231A0E351\r
+S3150000A380013783E2703083E20020A0E3002083E5FA\r
+S3150000A390080000EA0231A0E3013783E2703083E26D\r
+S3150000A3A00321A0E3002083E52231A0E3013783E205\r
+S3150000A3B00127A0E3002083E510209FE518305BE528\r
+S3150000A3C01130C2E50030A0E30300A0E100A81BE9BC\r
+S3150000A3D0943E02000DC0A0E100D82DE904B04CE285\r
+S3150000A3E008D04DE210000BE50030A0E314300BE579\r
+S3150000A3F010204BE2003092E50010D3E5013083E2F5\r
+S3150000A400003082E5FF3001E2000053E30000001A4D\r
+S3150000A410030000EA14301BE5013083E214300BE53B\r
+S3150000A420F2FFFFEA14301BE50300A0E100A81BE9D8\r
+S3150000A4300DC0A0E100D82DE904B04CE208D04DE2F1\r
+S3150000A44010000BE50130A0E111304BE5B4214BE1E2\r
+S3150000A450B4315BE1013043E2B4314BE10338A0E1B2\r
+S3150000A4602328A0E1FF3CA0E3FF3083E2030052E192\r
+S3150000A4700000001A070000EA10004BE2003090E5E9\r
+S3150000A4800310A0E111205BE50020C1E5013083E265\r
+S3150000A490003080E5EDFFFFEA00A81BE90DC0A0E152\r
+S3150000A4A000D82DE904B04CE210D04DE210000BE5C7\r
+S3150000A4B014100BE50230A0E1B6314BE10030A0E309\r
+S3150000A4C01C300BE5B6315BE1013043E2B6314BE1BE\r
+S3150000A4D00338A0E12328A0E1FF3CA0E3FF3083E29C\r
+S3150000A4E0030052E10000001A0F0000EA10004BE2E0\r
+S3150000A4F0002090E514104BE2003091E500C0D3E552\r
+S3150000A500013083E2003081E50030D2E5012082E2AD\r
+S3150000A510002080E5FF2003E2FF300CE2030052E159\r
+S3150000A520E7FFFF0A0130A0E31C300BE51C301BE5FA\r
+S3150000A5300300A0E100A81BE90DC0A0E100D82DE9A9\r
+S3150000A54004B04CE20CD04DE210000BE50B30E0E31A\r
+S3150000A5500C004BE2033080E0060083E810201BE588\r
+S3150000A5600231A0E3073983E2B03083E2003093E59D\r
+S3150000A570103082E510201BE50830A0E3033082E0AE\r
+S3150000A5800020A0E30010A0E3060083E810201BE5EE\r
+S3150000A5900B30E0E30C004BE2033080E0030093E86D\r
+S3150000A5A0030082E810201BE50030A0E3143082E5AA\r
+S3150000A5B000A81BE90DC0A0E110D82DE904B04CE2BB\r
+S3150000A5C008D04DE214000BE50231A0E3073983E21F\r
+S3150000A5D0B03083E2003093E518300BE514301BE50C\r
+S3150000A5E018201BE5103093E5030052E11000002A05\r
+S3150000A5F014201BE50830A0E303C082E014201BE50D\r
+S3150000A6000830A0E3030082E014301BE518201BE5A8\r
+S3150000A610103093E5023063E00310A0E10020A0E3D0\r
+S3150000A620180090E8013093E00240A4E018008CE89E\r
+S3150000A630140000EA14301BE518201BE5103093E5E2\r
+S3150000A640030052E10F00003A14201BE50830A0E396\r
+S3150000A65003C082E014201BE50830A0E3030082E07B\r
+S3150000A66014301BE518201BE5103093E5023063E03B\r
+S3150000A6700310A0E10020A0E3180090E8013093E069\r
+S3150000A6800240A4E018008CE814201BE518301BE5F6\r
+S3150000A690103082E514201BE50830A0E3033082E089\r
+S3150000A6A0180093E80410A0E10300A0E110A81BE93C\r
+S3150000A6B00DC0A0E100D82DE904B04CE210D04DE267\r
+S3150000A6C010000BE510201BE514200BE510001BE520\r
+S3150000A6D0B7FFFFEB20304BE2030083E914201BE5B4\r
+S3150000A6E0043092E518201BE5020053E10E00008AB3\r
+S3150000A6F014201BE5043092E518201BE5020053E107\r
+S3150000A7000600001A14201BE5003092E51C201BE50C\r
+S3150000A710020053E10400008A14201BE5003092E594\r
+S3150000A72010201BE50130A0E3143082E510301BE554\r
+S3150000A730143093E50300A0E100A81BE90DC0A0E1D9\r
+S3150000A74000D82DE904B04CE220D04DE210304BE2A7\r
+S3150000A750030003E82C304BE20300A0E110304BE28B\r
+S3150000A760060013E873FFFFEB2C304BE20300A0E179\r
+S3150000A770CEFFFFEB0030A0E1000053E3F9FFFF0A34\r
+S3150000A78000A81BE90DC0A0E130D82DE90040A0E1EA\r
+S3150000A79004B04CE2B000A0E37E3500EB0050A0E12F\r
+S3150000A7A0084084E2000055E30400A0E10530A0E182\r
+S3150000A7B00A00000A773500EB0030A0E300C0A0E1F4\r
+S3150000A7C00310A0E1A020A0E30500A0E1A03085E5EC\r
+S3150000A7D0AC3085E5A4C085E5322400EB0530A0E168\r
+S3150000A7E00300A0E130A81BE90DC0A0E110D82DE9B7\r
+S3150000A7F00040A0E104B04CE2AC0090E50FE0A0E11F\r
+S3150000A800A8F094E5A00094E5952400EBA40094E557\r
+S3150000A810713500EB0400A0E110681BE96E3500EA13\r
+S3150000A8200DC0A0E1F0DD2DE9000053E30360A0E1D7\r
+S3150000A830026BA00304B04CE210D04DE20080A0E110\r
+S3150000A8400600A0E101A0A0E10270A0E104509BE592\r
+S3150000A850CBFFFFEB000050E30040A0E108309BE592\r
+S3150000A860BC109FE50020A0E1A0E080E22500000AE0\r
+S3150000A870000055E3A4C090E50C50A003A88080E535\r
+S3150000A880AC7080E50500A0E100C08DE540408DE993\r
+S3150000A8900C408DE55A2400EBA03094E5000053E30C\r
+S3150000A8A00300A0E11000000A010073E30500000A9E\r
+S3150000A8B000005AE30100000A0400A0E1F0AD1BE924\r
+S3150000A8C07A2400EBFBFFFFEA58309FE558109FE51E\r
+S3150000A8D0000093E554209FE554309FE55FC0A0E358\r
+S3150000A8E000C08DE5DC3900EBD63500EB34309FE552\r
+S3150000A8F034109FE5000093E538209FE530309FE552\r
+S3150000A9005EC0A0E3F5FFFFEA18309FE518109FE54B\r
+S3150000A910000093E520209FE514309FE555C0A0E395\r
+S3150000A920EEFFFFEAE8A700009C120200BC0D020041\r
+S3150000A930E40D0200080E0200600E0200800E020006\r
+S3150000A9400DC0A0E110D82DE91400A0E304B04CE23C\r
+S3150000A95004D04DE20F3500EB000050E30040A0E1CB\r
+S3150000A9600500000A7D2600EB0400A0E10110A0E32B\r
+S3150000A970912600EB0400A0E110A81BE91C309FE51E\r
+S3150000A9806FC0A0E3000093E514109FE514209FE537\r
+S3150000A99014309FE500C08DE5AF3900EBA93500EB1B\r
+S3150000A9A09C120200BC0D0200940E0200080E02006A\r
+S3150000A9B00DC0A0E110D82DE9000050E304B04CE230\r
+S3150000A9C004D04DE20040A0E10300000A682600EB37\r
+S3150000A9D00400A0E110681BE9FF3400EA1C309FE583\r
+S3150000A9E078C0A0E3000093E514109FE514209FE5CE\r
+S3150000A9F014309FE500C08DE5973900EB913500EBEB\r
+S3150000AA009C120200BC0D0200940E0200080E020009\r
+S3150000AA100DC0A0E130D82DE904B04CE204D04DE2DF\r
+S3150000AA200040A0E10800A0E3DA3400EB000050E3A8\r
+S3150000AA300050A0E10410A0E10200000AEA2500EBA4\r
+S3150000AA400500A0E130A81BE91C309FE59EC0A0E3ED\r
+S3150000AA50000093E514109FE514209FE514309FE550\r
+S3150000AA6000C08DE57C3900EB763500EB9C120200C8\r
+S3150000AA70BC0D0200A40E0200080E02000DC0A0E1EB\r
+S3150000AA8010D82DE9000050E304B04CE204D04DE2AA\r
+S3150000AA900040A0E10300000AD82500EB0400A0E175\r
+S3150000AAA010681BE9CC3400EA1C309FE5A5C0A0E382\r
+S3150000AAB0000093E514109FE514209FE514309FE5F0\r
+S3150000AAC000C08DE5643900EB5E3500EB9C12020098\r
+S3150000AAD0BC0D0200A40E0200080E02000DC0A0E18B\r
+S3150000AAE010D82DE90800A0E304B04CE204D04DE2F2\r
+S3150000AAF0A83400EB000050E30040A0E10200000A89\r
+S3150000AB00D42500EB0400A0E110A81BE91C309FE54A\r
+S3150000AB10D4C0A0E3000093E514109FE514209FE540\r
+S3150000AB2014309FE500C08DE54B3900EB453500EB51\r
+S3150000AB309C120200BC0D0200B40E0200080E0200B8\r
+S3150000AB400DC0A0E110D82DE9000050E304B04CE29E\r
+S3150000AB5004D04DE20040A0E10300000AC32500EB4B\r
+S3150000AB600400A0E110681BE99B3400EA1C309FE555\r
+S3150000AB70DBC0A0E3000093E514109FE514209FE5D9\r
+S3150000AB8014309FE500C08DE5333900EB2D3500EB21\r
+S3150000AB909C120200BC0D0200B40E0200080E020058\r
+S3150000ABA00DC0A0E110D82DE93C00A0E304B04CE2B2\r
+S3150000ABB0783400EB000050E30040A0E1041080E28E\r
+S3150000ABC00030A0E10100000A5C2500EB0430A0E1A2\r
+S3150000ABD00300A0E110A81BE90DC0A0E110D82DE9E3\r
+S3150000ABE0000050E304B04CE204D04DE20040A0E186\r
+S3150000ABF00400000A000090E5592500EB0400A0E1DE\r
+S3150000AC0010681BE9743400EA1C309FE51CC09FE500\r
+S3150000AC10000093E518109FE518209FE518309FE582\r
+S3150000AC2000C08DE50C3900EB063500EB9C120200E6\r
+S3150000AC3021010000BC0D0200C40E0200080E020035\r
+S3150000AC400DC0A0E100D82DE9000050E304B04CE2AD\r
+S3150000AC5004D04DE20200000AA00090E500681BE95E\r
+S3150000AC608F2300EA1C309FE521C0A0E3000093E596\r
+S3150000AC7014109FE514209FE514309FE500C08DE574\r
+S3150000AC80F53800EBEF3400EB9C120200BC0D02001D\r
+S3150000AC90800E0200080E02000DC0A0E100D82DE9CA\r
+S3150000ACA0000050E304B04CE204D04DE20200000A7A\r
+S3150000ACB0A00090E500681BE97C2300EA1C309FE5B4\r
+S3150000ACC027C0A0E3000093E514109FE514209FE53C\r
+S3150000ACD014309FE500C08DE5DF3800EBD93400EB7A\r
+S3150000ACE09C120200BC0D0200800E0200080E02003B\r
+S3150000ACF00DC0A0E100D82DE9000050E304B04CE2FD\r
+S3150000AD0004D04DE20200000AA00090E500681BE9AD\r
+S3150000AD10722300EA1C309FE52DC0A0E3000093E5F6\r
+S3150000AD2014109FE514209FE514309FE500C08DE5C3\r
+S3150000AD30C93800EBC33400EB9C120200BC0D0200C4\r
+S3150000AD40800E0200080E02000DC0A0E100D82DE919\r
+S3150000AD50000050E304B04CE204D04DE20200000AC9\r
+S3150000AD60A00090E500681BE93D2300EA1C309FE542\r
+S3150000AD7033C0A0E3000093E514109FE514209FE57F\r
+S3150000AD8014309FE500C08DE5B33800EBAD3400EB21\r
+S3150000AD909C120200BC0D0200800E0200080E02008A\r
+S3150000ADA004E02DE5A00090E504E09DE44E2300EAD2\r
+S3150000ADB004E02DE504E09DE4262300EA04E02DE509\r
+S3150000ADC004E09DE4522300EA04E02DE50010A0E330\r
+S3150000ADD004E09DE4602300EA04E02DE504E09DE440\r
+S3150000ADE0442300EA0DC0A0E100D82DE9000050E39D\r
+S3150000ADF004B04CE204D04DE20100000A00681BE9F1\r
+S3150000AE005E2500EA1C309FE57FC0A0E3000093E5C5\r
+S3150000AE1014109FE514209FE514309FE500C08DE5D2\r
+S3150000AE208D3800EB873400EB9C120200BC0D02004B\r
+S3150000AE30940E0200080E02000DC0A0E100D82DE914\r
+S3150000AE40000050E304B04CE204D04DE20100000AD9\r
+S3150000AE5000681BE94C2500EA1C309FE585C0A0E38D\r
+S3150000AE60000093E514109FE514209FE514309FE53C\r
+S3150000AE7000C08DE5783800EB723400EB9C120200BE\r
+S3150000AE80BC0D0200940E0200080E02000DC0A0E1E7\r
+S3150000AE9000D82DE9000050E304B04CE204D04DE2A6\r
+S3150000AEA00200000A3B2500EB00681BE9112300EABB\r
+S3150000AEB01C309FE58BC0A0E3000093E514109FE5CE\r
+S3150000AEC014209FE514309FE500C08DE5623800EB45\r
+S3150000AED05C3400EB9C120200BC0D0200940E0200D2\r
+S3150000AEE0080E02000DC0A0E100D82DE9000050E3D5\r
+S3150000AEF004B04CE204D04DE20100000A00681BE9F0\r
+S3150000AF00272500EA1C309FE592C0A0E3000093E5E8\r
+S3150000AF1014109FE514209FE514309FE500C08DE5D1\r
+S3150000AF204D3800EB473400EB9C120200BC0D0200CA\r
+S3150000AF30940E0200080E02000DC0A0E100D82DE913\r
+S3150000AF40000050E304B04CE204D04DE20200000AD7\r
+S3150000AF50B62400EB00681BE9E62200EA1C309FE5F8\r
+S3150000AF60ADC0A0E3000093E514109FE514209FE513\r
+S3150000AF7014309FE500C08DE5373800EB313400EB27\r
+S3150000AF809C120200BC0D0200A40E0200080E020074\r
+S3150000AF900DC0A0E100D82DE9000050E304B04CE25A\r
+S3150000AFA004D04DE20100000A00681BE9962400EA7D\r
+S3150000AFB01C309FE5B4C0A0E3000093E514109FE5A4\r
+S3150000AFC014209FE514309FE500C08DE5223800EB84\r
+S3150000AFD01C3400EB9C120200BC0D0200A40E020001\r
+S3150000AFE0080E02000DC0A0E100D82DE9000050E3D4\r
+S3150000AFF004B04CE204D04DE20100000A00681BE9EF\r
+S3150000B000872400EA1C309FE5BAC0A0E3000093E560\r
+S3150000B01014109FE514209FE514309FE500C08DE5D0\r
+S3150000B0200D3800EB073400EB9C120200BC0D020049\r
+S3150000B030A40E0200080E02000DC0A0E170D82DE992\r
+S3150000B040000050E304B04CE204D04DE20050A0E111\r
+S3150000B0500160A0E10700000A0D2400EB0140A0E119\r
+S3150000B0600030A0E1061093E00500A0E10020A4E274\r
+S3150000B07070681BE9672400EA1C309FE5C0C0A0E3A6\r
+S3150000B080000093E514109FE514209FE514309FE51A\r
+S3150000B09000C08DE5F03700EBEA3300EB9C120200AE\r
+S3150000B0A0BC0D0200A40E0200080E02000DC0A0E1B5\r
+S3150000B0B000D82DE9000050E304B04CE208D04DE280\r
+S3150000B0C010104BE20200000A5B2400EB10001BE5A7\r
+S3150000B0D000A81BE91C309FE5C7C0A0E3000093E56C\r
+S3150000B0E014109FE514209FE514309FE500C08DE500\r
+S3150000B0F0D93700EBD33300EB9C120200BC0D0200E3\r
+S3150000B100A40E0200080E02000DC0A0E100D82DE931\r
+S3150000B110000050E304B04CE204D04DE20100000A06\r
+S3150000B12000681BE9542400EA1C309FE5E3C0A0E355\r
+S3150000B130000093E514109FE514209FE514309FE569\r
+S3150000B14000C08DE5C43700EBBE3300EB9C12020055\r
+S3150000B150BC0D0200B40E0200080E02000DC0A0E1F4\r
+S3150000B16000D82DE9000050E304B04CE204D04DE2D3\r
+S3150000B1700100000A00681BE9422400EA1C309FE532\r
+S3150000B180EAC0A0E3000093E514109FE514209FE5B4\r
+S3150000B19014309FE500C08DE5AF3700EBA93300EB17\r
+S3150000B1A09C120200BC0D0200B40E0200080E020042\r
+S3150000B1B00DC0A0E100D82DE9000050E304B04CE238\r
+S3150000B1C004D04DE2FF2002E20100000A00681BE9FC\r
+S3150000B1D02F2400EA1C309FE5F1C0A0E3000093E5B0\r
+S3150000B1E014109FE514209FE514309FE500C08DE5FF\r
+S3150000B1F0993700EB933300EB9C120200BC0D020062\r
+S3150000B200B40E0200080E02000DC0A0E1F0DF2DE929\r
+S3150000B210000050E304B04CE204D04DE20050A0E13F\r
+S3150000B2200380A0E10160A0E1FF7002E20D00000AC8\r
+S3150000B230972300EB0140A0E10030A0E1089093E0E5\r
+S3150000B24000A0A4E20500A0E10A50A0E10940A0E1A7\r
+S3150000B2500610A0E10430A0E10720A0E100508DE532\r
+S3150000B260162400EBF0AF1BE91C309FE5F9C0A0E304\r
+S3150000B270000093E514109FE514209FE514309FE528\r
+S3150000B28000C08DE5743700EB6E3300EB9C120200B4\r
+S3150000B290BC0D0200B40E0200080E02000DC0A0E1B3\r
+S3150000B2A000D82DE9000050E304B04CE204D04DE292\r
+S3150000B2B0FF2002E20100000A00681BE9162400EAEA\r
+S3150000B2C01C309FE501CCA0E3000093E514109FE538\r
+S3150000B2D014209FE514309FE500C08DE55E3700EB36\r
+S3150000B2E0583300EB9C120200BC0D0200B40E0200A3\r
+S3150000B2F0080E02000DC0A0E100D82DE9000050E3C1\r
+S3150000B30004B04CE204D04DE20100000A00681BE9DB\r
+S3150000B3100C2400EA1C309FE51CC09FE5000093E565\r
+S3150000B32018109FE518209FE518309FE500C08DE5B1\r
+S3150000B330493700EB433300EB9C1202000601000084\r
+S3150000B340BC0D0200B40E0200080E02000DC0A0E102\r
+S3150000B35000D82DE9000050E304B04CE204D04DE2E1\r
+S3150000B3600100000A00681BE9F82300EA1C309FE58B\r
+S3150000B37043CFA0E3000093E514109FE514209FE55A\r
+S3150000B38014309FE500C08DE5333700EB2D3300EB1D\r
+S3150000B3909C120200BC0D0200B40E0200080E020050\r
+S3150000B3A00DC0A0E100D82DE9000050E304B04CE246\r
+S3150000B3B004D04DE20200000A000090E500681BE997\r
+S3150000B3C06A2300EA1C309FE54ACFA0E3000093E51C\r
+S3150000B3D014109FE514209FE514309FE500C08DE50D\r
+S3150000B3E01D3700EB173300EB9C120200BC0D020068\r
+S3150000B3F0D80E0200080E02000DC0A0E1F0D82DE91B\r
+S3150000B400000050E304B04CE204D04DE20150A0E14C\r
+S3150000B4100800000A004090E51D2300EB056090E05F\r
+S3150000B4200070A1E20720A0E10610A0E10400A0E15F\r
+S3150000B430F0681BE9502300EA1C309FE51CC09FE51D\r
+S3150000B440000093E518109FE518209FE518309FE54A\r
+S3150000B45000C08DE5003700EBFA3200EB9C120200CB\r
+S3150000B4602E010000BC0D0200D80E0200080E0200DC\r
+S3150000B4700DC0A0E100D82DE9000050E304B04CE275\r
+S3150000B48004D04DE20200000A000090E500681BE9C6\r
+S3150000B4903C2300EA1C309FE51CC09FE5000093E5B5\r
+S3150000B4A018109FE518209FE518309FE500C08DE530\r
+S3150000B4B0E93600EBE33200EB9C1202003601000095\r
+S3150000B4C0BC0D0200D80E0200080E02000DC0A0E15D\r
+S3150000B4D000D82DE9000050E304B04CE204D04DE260\r
+S3150000B4E00200000A000090E500681BE9282300EA34\r
+S3150000B4F01C309FE54FCFA0E3000093E514109FE5B5\r
+S3150000B50014209FE514309FE500C08DE5D23600EB90\r
+S3150000B510CC3200EB9C120200BC0D0200D80E0200D9\r
+S3150000B520080E02000DC0A0E100D82DE9000050E38E\r
+S3150000B53004B04CE204D04DE20200000A000090E59F\r
+S3150000B54000681BE9152300EA1C309FE51CC09FE537\r
+S3150000B550000093E518109FE518209FE518309FE539\r
+S3150000B56000C08DE5BC3600EBB63200EB9C12020043\r
+S3150000B57042010000BC0D0200D80E0200080E0200B7\r
+S3150000B5800DC0A0E170D82DE9000050E304B04CE2F4\r
+S3150000B59004D04DE20250A0E10160A0E10700000ADC\r
+S3150000B5A0004090E5BA2200EB052090E00030A1E2D1\r
+S3150000B5B00400A0E10610A0E170681BE9FA2200EA87\r
+S3150000B5C01C309FE552CFA0E3000093E514109FE5E1\r
+S3150000B5D014209FE514309FE500C08DE59E3600EBF4\r
+S3150000B5E0983200EB9C120200BC0D0200D80E02003D\r
+S3150000B5F0080E02000DC0A0E100D82DE9000050E3BE\r
+S3150000B60004B04CE204D04DE20200000A000090E5CE\r
+S3150000B61000681BE9E72200EA1C309FE51CC09FE595\r
+S3150000B620000093E518109FE518209FE518309FE568\r
+S3150000B63000C08DE5883600EB823200EB9C120200DA\r
+S3150000B6404E010000BC0D0200D80E0200080E0200DA\r
+S3150000B6500DC0A0E100D82DE9000050E304B04CE293\r
+S3150000B66004D04DE20200000A000090E500681BE9E4\r
+S3150000B670D32200EA1C309FE555CFA0E3000093E5F6\r
+S3150000B68014109FE514209FE514309FE500C08DE55A\r
+S3150000B690713600EB6B3200EB9C120200BC0D02000F\r
+S3150000B6A0D80E0200080E02000DC0A0E100D82DE958\r
+S3150000B6B0000050E304B04CE204D04DE20200000A60\r
+S3150000B6C0000090E500681BE9BF2200EA1C309FE5F8\r
+S3150000B6D01CC09FE5000093E518109FE518209FE524\r
+S3150000B6E018309FE500C08DE55B3600EB553200EB68\r
+S3150000B6F09C1202005A010000BC0D0200D80E020086\r
+S3150000B700080E02000DC0A0E100D82DE9000050E3AC\r
+S3150000B71004B04CE204D04DE20200000A000090E5BD\r
+S3150000B72000681BE9AC2200EA1C309FE516CEA0E3B8\r
+S3150000B730000093E514109FE514209FE514309FE563\r
+S3150000B74000C08DE5443600EB3E3200EB9C12020051\r
+S3150000B750BC0D0200D80E0200080E020004309FE560\r
+S3150000B760000093E50EF0A0E14C1702000DC0A0E129\r
+S3150000B77010D82DE930309FE5003093E50040A0E178\r
+S3150000B78004B04CE20300A0E1A82200EB1C309FE5C8\r
+S3150000B7900228A0E3002083E50400A0E1043043E290\r
+S3150000B7A0002083E510681BE9E62100EA4417020041\r
+S3150000B7B0184002800DC0A0E110D82DE904B04CE27B\r
+S3150000B7C00040A0E1D92100EB0400A0E1E32100EB59\r
+S3150000B7D00209A0E3300900EB30109FE530009FE539\r
+S3150000B7E00238A0E3003081E50220A0E3023843E2FC\r
+S3150000B7F0003080E5002081E5423183E2002080E5CB\r
+S3150000B800012042E2002083E50300A0E310A81BE923\r
+S3150000B81018400280144002800DC0A0E170D82DE9C6\r
+S3150000B820A110A0E18130A0E104619FE504519FE5EC\r
+S3150000B830012083E0033080E0FCE09FE5FC409FE5CB\r
+S3150000B84004B04CE2022080E001C8A0E10CD04DE239\r
+S3150000B8500EC08CE3083086E5E4309FE5082085E5D8\r
+S3150000B860011080E00228A0E3081084E5002083E5AB\r
+S3150000B87000E085E504C085E510108EE808008EE539\r
+S3150000B88000E084E504C084E5201086E8022842E250\r
+S3150000B890AC309FE5003093E5020813E30200000A8E\r
+S3150000B8A0012082E2090052E3F8FFFF9A0A0052E300\r
+S3150000B8B01C00000A80E09FE588C09FE500E08CE55B\r
+S3150000B8C084C09FE50010A0E380409FE500C08DE5A1\r
+S3150000B8D07CC09FE50120A0E178309FE50500A0E34C\r
+S3150000B8E010108DE9692100EB000094E57C2100EB46\r
+S3150000B8F064109FE564C09FE50230A0E30228A0E340\r
+S3150000B900003081E50500A0E300308CE5002081E5EC\r
+S3150000B91000208CE58B2100EB44309FE50120A0E35D\r
+S3150000B9200020C3E570A81BE938009FE5D71E00EB91\r
+S3150000B930DFFFFFEA200000603000006000000060CA\r
+S3150000B9401000006000400280B04002806CB700002A\r
+S3150000B950C43E0200A83E0200B4B7000018400280B0\r
+S3150000B96014400280E0400280E40E020054329FE55B\r
+S3150000B970030050E150329FE5F0472DE94C229FE548\r
+S3150000B9804CE29FE501A0A0E300A083E50060A0E3F0\r
+S3150000B99040329FE50090A0E10301A0E300008EE5A0\r
+S3150000B9A0006082E50221A0E3042003E4006083E551\r
+S3150000B9B024329FE5040003E4006083E52040A0E311\r
+S3150000B9C0093983E214229FE500408EE5344083E482\r
+S3150000B9D0002083E508229FE5043043E2002083E54A\r
+S3150000B9E000229FE5013AA0E3003082E5F8319FE5A9\r
+S3150000B9F01070A0E3046083E6007083E5ECC19FE568\r
+S3150000BA00EC319FE5047002E4006082E50187A0E363\r
+S3150000BA1000308CE5072082E00154A0E3703043E259\r
+S3150000BA20003082E5CC019FE500808CE5008082E550\r
+S3150000BA3000508CE5005082E50FC0A0E30420A0E38F\r
+S3150000BA405E00000A4300008AFA0D59E33E00000A30\r
+S3150000BA502D00008AA0319FE5030059E12500000A68\r
+S3150000BA601F00008A7D0D59E31800000A0C38A0E17A\r
+S3150000BA70063C83E1003083E1000051E3023E83E1AE\r
+S3150000BA8078119FE578219FE5041002E4003082E5F5\r
+S3150000BA9070319FE50204A0E3040003E4000083E59F\r
+S3150000BAA01C2042024030A0030030820504204202DE\r
+S3150000BAB00030820518319FE52020A0E3002083E5B1\r
+S3150000BAC0202042E2043043E2002083E5F087BDE80F\r
+S3150000BAD00A20A0E10360A0E317C0A0E30E0CA0E3D8\r
+S3150000BAE0E1FFFFEA20319FE5030059E10A20A001AA\r
+S3150000BAF00360A003DCFFFFEA0A20A0E10360A0E3E5\r
+S3150000BB0011C0A0E33700A0E3D7FFFFEAFC309FE5B2\r
+S3150000BB10030059E10A20A0010A60A001D2FFFF0A32\r
+S3150000BB200500008AE8309FE5030059E1CEFFFF1AC1\r
+S3150000BB300A20A0E10A60A0E1F0FFFFEA7D0C59E3CC\r
+S3150000BB40C9FFFF1A0A20A0E1E2FFFFEA0A20A0E1EE\r
+S3150000BB500A60A0E1DFFFFFEAB8309FE5030059E184\r
+S3150000BB600220A003C0FFFF0A0D00008AFA0C59E369\r
+S3150000BB700900000A0300008A9C309FE5030059E192\r
+S3150000BB800A20A001B8FFFFEA90309FE5030059E1C3\r
+S3150000BB90B5FFFF1A0220A0E3D8FFFFEA0220A0E3C8\r
+S3150000BBA0CCFFFFEA78309FE5030059E1D3FFFF0A97\r
+S3150000BBB0ADFFFF8A7D0B59E3D0FFFF0AAAFFFFEA1C\r
+S3150000BBC00A20A0E1CDFFFFEA44AC0000B0C003802C\r
+S3150000BBD00480048008800480E88004800840028095\r
+S3150000BBE0FF01FF0100010001788004807480048059\r
+S3150000BBF088800480F0100000FF130000112B000065\r
+S3150000BC00FF1F1F772880048038800480E02E000004\r
+S3150000BC10C05D0000225600000077010080BB0000D6\r
+S3150000BC208858010010B1020030402DE974309FE5BC\r
+S3150000BC30001093E5000051E36C409FE56CE09FE542\r
+S3150000BC406C509FE50100A0E368C09FE53080BD18F9\r
+S3150000BC50000083E560309FE500E084E5003085E57F\r
+S3150000BC6058309FE5040003E4001083E50128A0E3B3\r
+S3150000BC701C3043E2042003E44C1003E4040003E414\r
+S3150000BC80000083E500E084E500309CE500209CE5AB\r
+S3150000BC900338A0E1FF3803E2FF2002E2023083E12D\r
+S3150000BCA0003085E53080BDE85017020038800480FA\r
+S3150000BCB0FF01FF01348004804817020000010001E3\r
+S3150000BCC0788004801C309FE50120A0E3002083E5F6\r
+S3150000BCD014309FE50010A0E3001083E50C309FE5CB\r
+S3150000BCE0001083E50EF0A0E10880048050170200E2\r
+S3150000BCF0048004800DC0A0E110D82DE904B04CE208\r
+S3150000BD000040A0E10400A0E11E10A0E3B9FDFFEB96\r
+S3150000BD102028B0E10008A0E14008A0E10400000AE4\r
+S3150000BD20040052E33D00000A380000CA010052E355\r
+S3150000BD303000000AEC109FE5ECC09FE5002091E57D\r
+S3150000BD4000309CE5030052E1EDFFFF0A002091E57B\r
+S3150000BD5000309CE5022063E0000052E3002062B25E\r
+S3150000BD600C0052E3C4309FC50400A0E39203C3C095\r
+S3150000BD70C20F43C0002091E500309CE5030052E16C\r
+S3150000BD801400003A003091E5033060E0003081E5B0\r
+S3150000BD90002091E500309CE5030052E10100002AF5\r
+S3150000BDA000309CE5003081E584209FE584309FE5E6\r
+S3150000BDB0002083E5003091E5002091E50338A0E1FD\r
+S3150000BDC0FF2002E2FF3803E2023083E168209FE5AC\r
+S3150000BDD0003082E5CAFFFFEA003091E5003083E0DB\r
+S3150000BDE0003081E5002091E500309CE5030052E13A\r
+S3150000BDF0ECFFFF9AE9FFFFEA0038A0E12308A0E183\r
+S3150000BE00F70050E320309F9500008395C8FFFFEAB6\r
+S3150000BE10050052E3C6FFFF1AA9FFFFEBC4FFFFEAC6\r
+S3150000BE2080FFFFEBC2FFFFEA481702004C17020033\r
+S3150000BE3056555555FF01FF01388004803480048033\r
+S3150000BE4004E02DE524309FE5003093E50118A0E1DC\r
+S3150000BE500020A0E12118A0E1000053E30300A0E1C7\r
+S3150000BE60021881E104F09D0404E09DE4ACFDFFEAC4\r
+S3150000BE70601702000DC0A0E1F0D82DE904B04CE235\r
+S3150000BE800050A0E1360100EB02CA60E2FFCECCE32F\r
+S3150000BE900FC0CCE300005CE3F0A81B09082095E581\r
+S3150000BEA0083095E503308CE0020A53E308309585A7\r
+S3150000BEB00C40A0E1024A638204605CE0083095050C\r
+S3150000BEC0043083000860851508308505083095E53F\r
+S3150000BED0020A53E308309525047095E5023A632279\r
+S3150000BEE008308525000054E3020087E00800001AA8\r
+S3150000BEF0000056E3F0A81B090700A0E10610A0E128\r
+S3150000BF0036F0FFEB0500A0E10610A0E1F0681BE9A2\r
+S3150000BF102F0100EA0410A0E130F0FFEB0500A0E1DC\r
+S3150000BF200410A0E12A0100EBF0FFFFEA0DC0A0E13A\r
+S3150000BF30F0DD2DE904B04CE20CC090E5027A6CE22B\r
+S3150000BF400280A0E10040A0E10708A0E1046094E5BA\r
+S3150000BF5020E8A0E108008CE00228A0E1020A50E3F4\r
+S3150000BF600150A0E10100A0E10130A0E30C1086E041\r
+S3150000BF702228A0E108A067E00CC086E00D00008A38\r
+S3150000BF80990600EB0C3094E5083083E00C3084E52C\r
+S3150000BF900C3094E5020A53E30C309425023A43220E\r
+S3150000BFA00C3084250400A0E10810A0E1180100EB84\r
+S3150000BFB00800A0E1F0AD1BE90C10A0E10E20A0E105\r
+S3150000BFC00500A0E10130A0E3870600EB0A28A0E106\r
+S3150000BFD0070085E02228A0E10610A0E10130A0E3D9\r
+S3150000BFE0810600EB0CA084E5EDFFFFEA0DC0A0E1A1\r
+S3150000BFF010D82DE904B04CE20040A0E110309FE5D6\r
+S3150000C000000093E5E1FBFFEB0400A0E198FFFFEBE6\r
+S3150000C010F9FFFFEA401702000DC0A0E1F0D92DE9B3\r
+S3150000C02004B04CE20040A0E10180A0E1007090E580\r
+S3150000C030B90000EB141094E5010050E1003061E016\r
+S3150000C0400060A0E3023A61320060A031000058E3CC\r
+S3150000C0500060A013023AA01314608415060073E171\r
+S3150000C0600050A0E1011087E00400A0E10320A0E158\r
+S3150000C0700100001A145084E5F0A91BE9AAFFFFEBA2\r
+S3150000C080000056E30620A0E10400A0E1F8FFFF0A45\r
+S3150000C090001094E5A4FFFFEBF5FFFFEA0DC0A0E159\r
+S3150000C0A010D82DE904B04CE20040A0E134309FE501\r
+S3150000C0B0003093E5000053E32800A0E30100001AD6\r
+S3150000C0C040FBFFEBF8FFFFEA0300A0E1AFFBFFEB4D\r
+S3150000C0D00400A0E10010A0E3CEFFFFEB0400A0E106\r
+S3150000C0E063FFFFEBF0FFFFEA441702000DC0A0E17B\r
+S3150000C0F0F0DF2DE904B04CE2CCC19FE508D04DE25B\r
+S3150000C1000070A0E100509CE5000055E30180A0E12D\r
+S3150000C11002A0A0E1F0AF1B19B0419FE5003094E505\r
+S3150000C1200190A0E3000053E300908CE56200000A52\r
+S3150000C13002FAFFEB98319FE50020A0E1002083E59D\r
+S3150000C1400500A0E131FAFFEB88619FE588319FE5A4\r
+S3150000C15000C0A0E100C083E51820A0E30600A0E12E\r
+S3150000C1600510A0E1CF1D00EB70019FE570319FE542\r
+S3150000C170000050E3040086E5003086E54C00000A26\r
+S3150000C180000053E34800000A000050E33F00000AA5\r
+S3150000C190000053E33400000A48419FE50510A0E182\r
+S3150000C1A00420A0E1BF1D00EB0420A0E10510A0E1E2\r
+S3150000C1B0000096E5BB1D00EB2C319FE5012047E210\r
+S3150000C1C000C096E5002083E520319FE50C00A0E144\r
+S3150000C1D000C083E50710A0E18EFDFFEB0A10A0E189\r
+S3150000C1E00800A0E1E0FDFFEB0600A0E120FFFFEB69\r
+S3150000C1F00910A0E10600A0E186FFFFEB0600A0E122\r
+S3150000C2001BFFFFEB0510A0E10620A0E10530A0E131\r
+S3150000C210DC009FE500508DE504508DE57FF9FFEBCE\r
+S3150000C2200620A0E10510A0E10530A0E1C4009FE5CD\r
+S3150000C23000508DE504508DE578F9FFEB57FAFFEBDA\r
+S3150000C240B4C09FE500E0A0E100E08CE50510A0E1A8\r
+S3150000C2500E20A0E10530A0E1A0009FE500508DE58D\r
+S3150000C26004508DE56DF9FFEBF0AF1BE990309FE5CB\r
+S3150000C27090109FE5000093E58C209FE58C309FE5AC\r
+S3150000C2808CC09FE500C08DE5733300EB6D2F00EB8E\r
+S3150000C2906C309FE56C109FE5000093E574209FE5E8\r
+S3150000C2A068309FE5A6CFA0E3F5FFFFEA0000FDFF9B\r
+S3150000C2B0B4FFFFEA0000FDFFB0FFFFEA0500A0E1C2\r
+S3150000C2C0D2F9FFEB000084E598FFFFEA541702005D\r
+S3150000C2D0441702003C17020040B10200401702005A\r
+S3150000C2E0C83E0200CA5E0200022000005817020083\r
+S3150000C2F05C170200ECBF00009CC000006017020043\r
+S3150000C300F4BC00009C120200BC0D02001C0F0200CF\r
+S3150000C310400F020099020000980F020030309FE59E\r
+S3150000C320000093E5000050E30EF0A00124309FE5E5\r
+S3150000C330003093E520309FE5002093E51C309FE513\r
+S3150000C340003093E5033062E0FF0EC3E30F00C0E365\r
+S3150000C3500EF0A0E154170200004102805C170200B3\r
+S3150000C360D04002800DC0A0E130D82DE924409FE5E1\r
+S3150000C370003094E504B04CE20050A0E10300A0E1D7\r
+S3150000C38097FAFFEB000094E5104095E5BEFAFFEB47\r
+S3150000C3900400A0E130A81BE93C1702000DC0A0E193\r
+S3150000C3A070D82DE924509FE5003095E50060A0E1A6\r
+S3150000C3B004B04CE20300A0E10140A0E188FAFFEBE3\r
+S3150000C3C0000095E5104086E570681BE9AEFAFFEAC5\r
+S3150000C3D03C1702000DC0A0E170D82DE92C509FE556\r
+S3150000C3E0003095E50060A0E104B04CE20300A0E156\r
+S3150000C3F00140A0E17AFAFFEB103096E5000095E5E2\r
+S3150000C400043083E0103086E570681BE99EFAFFEA87\r
+S3150000C4103C1702000DC0A0E170D82DE93C409FE515\r
+S3150000C420003094E50060A0E104B04CE20300A0E116\r
+S3150000C4300150A0E16AFAFFEB103096E5033065E0A3\r
+S3150000C440103086E5103096E5000094E5000053E3D1\r
+S3150000C4500030A0B3103086B570681BE98AFAFFEA8F\r
+S3150000C4603C1702000DC0A0E110D82DE930409FE531\r
+S3150000C470003094E50000A0E3000053E104B04CE274\r
+S3150000C48010A81B09510000EB000094E554FAFFEBDD\r
+S3150000C490000094E545F9FFEB0030A0E3003084E5A9\r
+S3150000C4A010A81BE96C1702000DC0A0E170D82DE999\r
+S3150000C4B0E4409FE504B04CE204D04DE2003094E540\r
+S3150000C4C0000053E32800000A000094E5000050E352\r
+S3150000C4D02800000A42FAFFEBC0509FE55B0300EB21\r
+S3150000C4E0BC309FE5BC609FE5003085E5B8309FE530\r
+S3150000C4F0B8109FE5003086E50040A0E3003091E5E6\r
+S3150000C500004081E5A8309FE5002091E5033082E1F7\r
+S3150000C510003081E55F0300EB0A00A0E3D00200EBE8\r
+S3150000C5200138A0E3003085E5003086E584509FE5BC\r
+S3150000C5300430D5E7FF0053E30500000A0500D4E701\r
+S3150000C540014084E22E0300EB0430D5E7FF0053E3FD\r
+S3150000C550F9FFFF1A40309FE5000093E54AFAFFEB2A\r
+S3150000C5600000A0E370681BE9180000EAF3F8FFEB8F\r
+S3150000C570000084E5D3FFFFEA3C309FE53CC09FE521\r
+S3150000C580000093E538109FE538209FE538309FE599\r
+S3150000C59000C08DE5B03200EBAA2E00EB6C1702004E\r
+S3150000C5A008000680FFFF6E000400068001000A00F6\r
+S3150000C5B01000068005050505741702009C1202008E\r
+S3150000C5C075010000BC0D0200C00F0200D40F02006E\r
+S3150000C5D004E02DE50010A0E10000A0E304E09DE4E6\r
+S3150000C5E0040000EA04E02DE50010A0E1FF00A0E34E\r
+S3150000C5F004E09DE4FFFFFFEA3C209FE5FF30A0E357\r
+S3150000C60004E02DE5003082E530209FE5213E83E2FF\r
+S3150000C610FF0000E2013053E20100C2E4FCFFFF5AD2\r
+S3150000C6201C209FE56130A0E3013053E20100C2E423\r
+S3150000C630FCFFFF5A04E09DE4890100EA701702003E\r
+S3150000C64050000060600300600DC0A0E1F0DF2DE93E\r
+S3150000C6500280A0E1A12FA0E1000058E3012082D3CF\r
+S3150000C66004B04CE2000052E30370A0E104609BE5D5\r
+S3150000C6700B00001A000056E30030A0C30130A0D31F\r
+S3150000C6803F0051E3013083C3000053E30400001A66\r
+S3150000C690610057E30030A0D30130A0C3A73F93E168\r
+S3150000C6A00100000A0000A0E3F0AF1BE9083081E0BA\r
+S3150000C6B0400053E3063087E0408061C2620053E3E6\r
+S3150000C6C0626067C208A081E0000050E3FF90A013FB\r
+S3150000C6D00090A0030A0051E10150A0E11C0000AA4D\r
+S3150000C6E078E09FE5C501A0E101C0A0E3073005E2BF\r
+S3150000C6F01C33A0E1802160E000109EE5FF4003E2CC\r
+S3150000C700822162E058309FE51C1081E1822087E09B\r
+S3150000C7100400E0E1000056E304C009E000108EE5E5\r
+S3150000C720032082E0FF4000E2060000BA011086E224\r
+S3150000C7300030D2E5033004E003308CE1011051E211\r
+S3150000C7400130C2E4F9FFFF1A015085E20A0055E103\r
+S3150000C750E2FFFFBA420100EB0800A0E1F0AF1BE9DF\r
+S3150000C76070170200500000600DC0A0E110D82DE93E\r
+S3150000C7700140A0E10010A0E10000A0E304B04CE2FB\r
+S3150000C78004D04DE262C0A0E30420A0E10030A0E1A5\r
+S3150000C79000C08DE5ABFFFFEB0400A0E110A81BE98C\r
+S3150000C7A0F0452DE9202042E2FF2002E2D4409FE539\r
+S3150000C7B05F0052E3C001A0E10150A0E100C094E592\r
+S3150000C7C01F20A083801160E0811161E0026182E098\r
+S3150000C7D00120A0E38110A0E112C08CE1610055E3C5\r
+S3150000C7E0058081E000C084E59CA09FE59C709FE5E4\r
+S3150000C7F0025085E00340A0E11E0000CA0A30D6E7D9\r
+S3150000C800610055E305C081E00A2086E0015085E21B\r
+S3150000C8100730C8E7170000CA0130D2E5610055E3CA\r
+S3150000C820050081E00730CCE7015085E2110000CA1F\r
+S3150000C8300230D2E5610055E305C081E00730C0E76C\r
+S3150000C840015085E20B0000CA0330D2E5610055E3D2\r
+S3150000C850050081E00730CCE7015085E2050000CAFB\r
+S3150000C8600430D2E5610055E30730C0E7051081E0EA\r
+S3150000C8700030A0D30730C1D7010054E3F085BD18BE\r
+S3150000C880F045BDE8F60000EA701702007F170200C7\r
+S3150000C890500000600DC0A0E1F0D82DE90250A0E1E3\r
+S3150000C8A00020D2E5000052E304B04CE20070A0E1A3\r
+S3150000C8B00140A0E10060A0E30200001AE80000EBDE\r
+S3150000C8C00600A0E1F0A81BE90410A0E10030A0E3F7\r
+S3150000C8D00700A0E1B1FFFFEB0120F5E5016086E26C\r
+S3150000C8E0630056E30030A0C30130A0D3FF2002E26C\r
+S3150000C8F0000052E30030A00301300312000053E3AE\r
+S3150000C900064084E2EFFFFF1AEBFFFFEA0DC0A0E14D\r
+S3150000C910F0DF2DE90280A0E1072082E2C221A0E13A\r
+S3150000C920201081E20050A0E304B04CE23CD04DE27E\r
+S3150000C9301F10C1E3020055E144200BE53C000BE566\r
+S3150000C94040300BE5C161A0E1700000AA0090A0E3B1\r
+S3150000C950060059E140701BE55F0000AA28304BE253\r
+S3150000C96007C0A0E30020A0E301C05CE2082043E585\r
+S3150000C970013083E2FAFFFF5A8501A0E1080050E189\r
+S3150000C98002C0A0E148000BE50C0000AA3C101BE524\r
+S3150000C990093081E0963022E028104BE20030D2E5E3\r
+S3150000C9A001C08CE2010080E207005CE3080050D180\r
+S3150000C9B0083041E5062082E0011081E2F6FFFFBA69\r
+S3150000C9C048201BE5000052E180E0A0E300C0A0E3A0\r
+S3150000C9D02E0000AA29305BE52A105BE52B205BE5DB\r
+S3150000C9E04C304BE550104BE554204BE52C305BE5C5\r
+S3150000C9F02D105BE52E205BE558304BE55C104BE5D2\r
+S3150000CA0060204BE52FA05BE528404BE24C105BE530\r
+S3150000CA1001300EE050105BE501200EE054105BE59E\r
+S3150000CA20833082E101200EE058105BE5833082E11D\r
+S3150000CA3001200EE05C105BE5833082E101200EE010\r
+S3150000CA4060105BE5833082E101200EE0833082E1F5\r
+S3150000CA5030205BE50A100EE002200EE0833081E113\r
+S3150000CA60833082E148201BE507106CE201C08CE2AE\r
+S3150000CA7002208CE03331A0E1000052E164200BE596\r
+S3150000CA80AEE0A0E1103044E5014084E2DEFFFFBAEB\r
+S3150000CA9028004BE207C0A0E304109BE5C13FA0E1DC\r
+S3150000CAA0A33E81E0C33185E0833163E0101050E599\r
+S3150000CAB0833163E060209FE5833087E001C05CE25C\r
+S3150000CAC00210C3E7017087E2010080E2F1FFFF5A1E\r
+S3150000CAD0019089E2060059E19FFFFFBA04209BE519\r
+S3150000CAE038009FE5C23FA0E1A33E82E0001090E53A\r
+S3150000CAF0C33185E00120A0E3121381E144301BE538\r
+S3150000CB00015085E2030055E1001080E58EFFFFBA73\r
+S3150000CB10530000EB0000A0E3F0AF1BE950000060FB\r
+S3150000CB20701702000DC0A0E1F0DF2DE904B04CE261\r
+S3150000CB3004D04DE21FC081E204509BE501E0A0E174\r
+S3150000CB400380A0E10270A0E1073005E2022085E043\r
+S3150000CB50FF10A0E31FC0CCE35113A0E1012042E285\r
+S3150000CB600E3088E00CC06EE0620058E3400055D3FA\r
+S3150000CB700040A0E1C2A1A0E1016043E22CC00BE5A8\r
+S3150000CB80FF9001E2220000CA00005EE3000057C3E6\r
+S3150000CB901F0000DAC501A0E10A0050E11B0000CA2F\r
+S3150000CBA0803160E0833163E083C0A0E10C50A0E1F6\r
+S3150000CBB00A0050E11800000A060058E108E0A0E16A\r
+S3150000CBC0060000CA90309FE50120D4E4033085E0DA\r
+S3150000CBD00E20C3E701E08EE206005EE1F8FFFFDA11\r
+S3150000CBE078109FE5002091E50130A0E3132082E153\r
+S3150000CBF0030080E02C301BE50A0050E1002081E5AF\r
+S3150000CC00034084E062C08CE2625085E2E7FFFFDA0F\r
+S3150000CC10130000EB0000A0E3F0AF1BE9060058E1AB\r
+S3150000CC2008E0A0E1EDFFFFCA2C109FE501108CE0A3\r
+S3150000CC300E20D1E70920C2E10E20C1E70130D4E47D\r
+S3150000CC40033009E0032082E10E20C1E701E08EE215\r
+S3150000CC5006005EE1F3FFFFDAE0FFFFEA5000006046\r
+S3150000CC60701702000DC0A0E1F0D82DE9EC329FE567\r
+S3150000CC7004B04CE204D04DE20060A0E3000093E56E\r
+S3150000CC8057F8FFEBD8329FE5003093E5000053E3F9\r
+S3150000CC90D0329FE50050D3E56100001A060055E149\r
+S3150000CCA00600000A0670A0E1010015E30A00001A5A\r
+S3150000CCB0A550B0E1077087E2016086E2F9FFFF1A2E\r
+S3150000CCC098329FE5000093E598329FE50020A0E3A7\r
+S3150000CCD0002083E5F0681BE96BF8FFEA8601A0E116\r
+S3150000CCE0FA0000EB0000A0E3130100EB78329FE5A9\r
+S3150000CCF0003093E5010053E31800000A6200A0E348\r
+S3150000CD00E40000EB64229FE50138A0E3043002E46E\r
+S3150000CD10003082E50040A0E354229FE5873167E0BA\r
+S3150000CD20832082E00400D2E7014084E2340100EB74\r
+S3150000CD30610054E3F7FFFFDA38329FE5003093E5F0\r
+S3150000CD40010813E3D9FFFF0A6A1B00EB24329FE5B3\r
+S3150000CD50003093E5010813E3FAFFFF1AD3FFFFEA59\r
+S3150000CD606240A0E308329FE5872167E0014044E284\r
+S3150000CD70822083E00420D2E7033084E0313E83E260\r
+S3150000CD80000054E30020C3E5F5FFFF1A650100EB40\r
+S3150000CD90000050E31F00001ADC219FE5DC319FE50F\r
+S3150000CDA0002083E51020A0E37A3F43E2002083E5DC\r
+S3150000CDB0CC119FE5043043E2004083E50130A0E357\r
+S3150000CDC00030C1E50230D1E5000053E3F62F82E2E0\r
+S3150000CDD00D00000AA8319FE50230D3E5000053E3B9\r
+S3150000CDE0012042E20800000A000052E3F8FFFF1AA1\r
+S3150000CDF090319FE590119FE5000093E58C219FE51A\r
+S3150000CE008C319FE58CC19FE54E0000EA000052E39D\r
+S3150000CE10A6FFFF1AF5FFFFEA40319FE5000093E504\r
+S3150000CE20ABFFFFEAFF5015E20060A0E3A3FFFF0A95\r
+S3150000CE300670A0E1010015E30400001AA550B0E158\r
+S3150000CE40627087E2016086E2F9FFFF1A9BFFFFEA44\r
+S3150000CE50070066E28001A0E19C0000EB0000A0E371\r
+S3150000CE60B50000EB30019FE5311E40E2011087E07E\r
+S3150000CE706220A0E34A0000EBEC309FE5004093E51A\r
+S3150000CE80010054E31600000A6200A0E3810000EBF3\r
+S3150000CE90D8209FE50138A0E3043002E4003082E5A3\r
+S3150000CEA00040A0E3F0309FE50300D4E7014084E2B0\r
+S3150000CEB0D30000EB610054E3F9FFFFDAB4309FE5DD\r
+S3150000CEC0003093E5010813E3DBFFFF0A091B00EBC3\r
+S3150000CED0A0309FE5003093E5010813E3FAFFFF1A3F\r
+S3150000CEE0D5FFFFEA0F0100EB000050E3C9FFFF1A70\r
+S3150000CEF08C109FE580209FE580309FE5002083E52C\r
+S3150000CF000040C1E50230D1E5000053E3FA2FA0E36B\r
+S3150000CF100F00000A68309FE50230D3E5000053E3B6\r
+S3150000CF20012042E20A00000A000052E3F8FFFF1A5D\r
+S3150000CF3050309FE550109FE5000093E54C209FE59B\r
+S3150000CF404C309FE554C09FE500C08DE5423000EBB4\r
+S3150000CF503C2C00EB000052E3B7FFFF1AF3FFFFEA99\r
+S3150000CF606C170200641702007017020068170200AF\r
+S3150000CF700800068050000060000006804000006047\r
+S3150000CF8000420280304202809C120200BC0D020068\r
+S3150000CF9028100200D40F020018040000600300608D\r
+S3150000CFA05C040000F0412DE9023081E00240A0E17E\r
+S3150000CFB0000052E3022080E00060A0E10150A0E101\r
+S3150000CFC0018043E2017042E2F081BDD801C0D5E4A0\r
+S3150000CFD001E058E402200CE202300EE201100CE2FD\r
+S3150000CFE001000EE28222A0E18332A0E1812382E1E8\r
+S3150000CFF0803383E104100CE204000EE2812182E119\r
+S3150000D000803183E108100CE208000EE2812082E103\r
+S3150000D010803083E110100CE210000EE2A12082E1C4\r
+S3150000D020A03083E120100CE220000EE2A12182E173\r
+S3150000D030A03183E140100CE240000EE2A12282E121\r
+S3150000D040A03283E1024044E2AC2382E1AE3383E1C5\r
+S3150000D050000054E30130C6E4012047E4F081BDD866\r
+S3150000D060D9FFFFEA20209FE520309FE5003082E5CA\r
+S3150000D070013783E2003082E50008A0E110309FE529\r
+S3150000D0802008A0E1000083E50EF0A0E1080006807C\r
+S3150000D090FFFF00000400068024209FE524309FE562\r
+S3150000D0A0FF04C0E3003082E5013783E2003082E509\r
+S3150000D0B0FB08C0E310309FE5010780E3000083E52D\r
+S3150000D0C00EF0A0E108000680FFFF000004000680C5\r
+S3150000D0D00DC0A0E110D82DE904B04CE2C041A0E19A\r
+S3150000D0E00100A0E3DEFFFFEB44309FE50128A0E34B\r
+S3150000D0F00F4004E2002083E5B04084E3043043E2BD\r
+S3150000D100002083E50400A0E13D0000EB24309FE50C\r
+S3150000D110003093E5010813E310A81B09751A00EB0C\r
+S3150000D12010309FE5003093E5010813E310A81B09B2\r
+S3150000D130F9FFFFEA08000680000006800DC0A0E1A6\r
+S3150000D14010D82DE904B04CE20040A0E10200A0E3B3\r
+S3150000D150C3FFFFEB50309FE50128A0E34402A0E1A6\r
+S3150000D160002083E50F0000E2043043E2002083E55F\r
+S3150000D170100080E30F4004E2210000EB0400A0E170\r
+S3150000D1801F0000EB24309FE5003093E5010813E310\r
+S3150000D19010A81B09571A00EB10309FE5003093E5E5\r
+S3150000D1A0010813E310A81B09F9FFFFEA080006802F\r
+S3150000D1B00000068070402DE93C609FE5C1CFA0E1EC\r
+S3150000D1C0AC1E81E0005096E5C111A0E101C0A0E3CC\r
+S3150000D1D0814161E01C5185E120109FE5844164E0B6\r
+S3150000D1E0841081E00C0053E10020C1E7005086E581\r
+S3150000D1F07080BD187040BDE899FEFFEA7017020006\r
+S3150000D200500000600DC0A0E110D82DE934309FE534\r
+S3150000D2100330D3E5010013E304B04CE2FF4000E223\r
+S3150000D2200200000A20309FE50040C3E510A81BE974\r
+S3150000D230301A00EB0C309FE50330D3E5010013E311\r
+S3150000D240FAFFFF0AF6FFFFEA0000068020000680CC\r
+S3150000D25034209FE534109FE500C0A0E30201A0E35F\r
+S3150000D2600131A0E3003082E500C081E520309FE572\r
+S3150000D270000082E5000081E5003093E50331A0E37C\r
+S3150000D280003082E500C081E50EF0A0E108000680CE\r
+S3150000D290040006800000068044209FE544109FE5B8\r
+S3150000D2A00136A0E3003082E5003081E5003082E5FA\r
+S3150000D2B034309FE50000A0E3000081E5000083E52F\r
+S3150000D2C024309FE5003093E5010053E3FBFFFF9A0E\r
+S3150000D2D00C209FE50136A0E3043002E4003082E52D\r
+S3150000D2E00EF0A0E10800068004000680B0C00180B0\r
+S3150000D2F0003180E0033183E00301A0E1000050E348\r
+S3150000D3000EF0A0D118209FE50137A0E3003082E59A\r
+S3150000D310010050E2042042E2003082E50EF0A00156\r
+S3150000D320F7FFFFEA080006800DC0A0E100D82DE94E\r
+S3150000D33070309FE50126A0E304B04CE204D04DE234\r
+S3150000D340002083E5003093E5010613E30A20A0E3FD\r
+S3150000D3500700000A4C309FE5003093E5010613E311\r
+S3150000D360012042E20200000A000052E3F8FFFF1A21\r
+S3150000D370030000EA000052E30100000A0000A0E3F7\r
+S3150000D38000A81BE920309FE520C09FE5000093E53B\r
+S3150000D3901C109FE51C209FE51C309FE500C08DE515\r
+S3150000D3A02D2F00EB272B00EB004002809C12020081\r
+S3150000D3B0BE050000BC0D020028100200D40F0200BA\r
+S3150000D3C00DC0A0E100D82DE904B04CE2E31A00EB51\r
+S3150000D3D01C209FE50138A0E3003082E50110A0E3A0\r
+S3150000D3E04231A0E3001082E50300A0E3001083E5CC\r
+S3150000D3F000A81BE918000580010070E300C0A0E347\r
+S3150000D4002200000AB4109FE5002191E7020212E310\r
+S3150000D41001C0A0130532A0130200001A010112E395\r
+S3150000D4200F00000A0231A0E3003181E70020A0E3EB\r
+S3150000D430000052E184109FE50400000A023191E7E2\r
+S3150000D440020213E30332A0030231810701C0A003E5\r
+S3150000D450012082E20C0052E3F4FFFFDA0C00A0E1A7\r
+S3150000D4600EF0A0E1000052E3EFFFFFAA012082E2E6\r
+S3150000D4700238A0E12338A0E10E0053E30932A0836D\r
+S3150000D480002181E70031818701C0A083E6FFFFEA22\r
+S3150000D4900C20A0E124109FE5023191E7070173E318\r
+S3150000D4A00332A0830232A093023181E7012082E297\r
+S3150000D4B001C0A0830C0052E3F5FFFFDAE6FFFFEAA6\r
+S3150000D4C060B102000DC0A0E170D82DE9FC309FE5E7\r
+S3150000D4D0B020D3E1F8309FE5B020C3E1F4309FE5FA\r
+S3150000D4E0002093E5022AA0E1222AA0E1000052E3EF\r
+S3150000D4F004B04CE20050E0E30060A0E32900000A1B\r
+S3150000D500603083E2001093E5011AA0E1823262E006\r
+S3150000D510211AA0E1033182E0060051E18301A0E176\r
+S3150000D5202000000AAF3F00EBAC309FE5030050E15E\r
+S3150000D5300E00008A06C0A0E10610A0E19C209FE52F\r
+S3150000D540B23091E1030050E1023081E01A1081E22D\r
+S3150000D5500300003AB230D3E1030050E10C50A09131\r
+S3150000D5600200009A01C08CE20A005CE3F2FFFFDAD7\r
+S3150000D5706C409FE5003094E5030055E10D00000A7C\r
+S3150000D580005084E5000056E30300001A40309FE592\r
+S3150000D590B030D3E1000053E30200000A44309FE5B7\r
+S3150000D5A0000093E5211B00EB3C309FE50128A0E33A\r
+S3150000D5B0002083E570A81BE90500A0E18DFFFFEBC5\r
+S3150000D5C06230E0E30060A0E1003084E5ECFFFFEAB2\r
+S3150000D5D010800680B81A020050000580A2030000E1\r
+S3150000D5E060190200BC1A0200B41A02001400058079\r
+S3150000D5F00DC0A0E110D82DE904B04CE2F4309FE54F\r
+S3150000D6006410A0E3000093E58AF6FFEB000050E308\r
+S3150000D6102F00000AE0309FE500C093E500005CE3C0\r
+S3150000D6200B00000AD4209FE5B030D2E1000053E39E\r
+S3150000D6300700000AB010D2E10030A0E30118A0E113\r
+S3150000D6404118A0E1B030C2E16300A0E30FE0A0E121\r
+S3150000D6500CF0A0E10040A0E3A4109FE5042191E7AF\r
+S3150000D660010212E30E00000A8C309FE5003093E5BC\r
+S3150000D6700122C2E3000053E3042181E70800000A07\r
+S3150000D680010152E30400A0010210A0030800000AF1\r
+S3150000D6900A00008A020252E30400A0010110A0035E\r
+S3150000D6A00300000A014084E20C0054E3E9FFFFDABC\r
+S3150000D6B0D1FFFFEA0FE0A0E103F0A0E1F8FFFFEAE7\r
+S3150000D6C0020152E30400A0010410A003F4FFFF1AB4\r
+S3150000D6D0F7FFFFEA20309FE5003093E5000053E3B3\r
+S3150000D6E0C5FFFF0A0010A0E10000E0E30FE0A0E1A3\r
+S3150000D6F003F0A0E1C0FFFFEAB41A0200C01A02005C\r
+S3150000D700B81A020060B102002C209FE52C309FE57C\r
+S3150000D7102C109FE5003082E5313E43E2003081E582\r
+S3150000D720033BA0E3003082E5013B43E2003081E5A4\r
+S3150000D73010309FE5B030D3E10EF0A0E108800680FE\r
+S3150000D7407713000004800680108006800DC0A0E1DB\r
+S3150000D750F0DF2DE904B04CE240C19FE50CD04DE26C\r
+S3150000D7600040A0E338519FE500C08DE534C19FE538\r
+S3150000D7700410A0E10420A0E12C319FE52500A0E3E0\r
+S3150000D78020108DE9C11900EB000095E5D41900EBD6\r
+S3150000D79018319FE518119FE5032CA0E3002083E5CF\r
+S3150000D7A0013BA0E3004081E5003081E504319FE5BF\r
+S3150000D7B00000E0E3000083E5FC609FE5FCA09FE538\r
+S3150000D7C0FC909FE5603083E2000083E5F4709FE5FE\r
+S3150000D7D01358A0E30186A0E30135A0E300508AE5D3\r
+S3150000D7E0008089E5003086E5033083E0004087E568\r
+S3150000D7F0D4209FE5003086E5D0309FE5004087E5E0\r
+S3150000D800002083E50124A0E3AC3043E2002083E559\r
+S3150000D810C120A0E3203043E2002083E5B9FFFFEBFF\r
+S3150000D820AC309FE50226A0E39C8003E400508AE525\r
+S3150000D830005089E5042003E4002083E594209FE559\r
+S3150000D840003092E57F37C3E30338C3E3003082E557\r
+S3150000D850003092E5C63883E3003082E5003092E579\r
+S3150000D860013CC3E3003082E5003092E5013C83E3EE\r
+S3150000D870003082E560309FE5003093E55C309FE53F\r
+S3150000D880003093E50130A0E3003086E52500A0E3F3\r
+S3150000D8900138A0E3003087E5F06F1BE9A91900EA1B\r
+S3150000D8A0C4D40000E87E0200CC7E0200C0D3000093\r
+S3150000D8B0F8000080F40000805800058018000580FC\r
+S3150000D8C0380105803401058014000580140001C16B\r
+S3150000D8D0D0000580D40005805040048050000580AB\r
+S3150000D8E0B00005800DC0A0E130D82DE9A4509FE519\r
+S3150000D8F004B04CE208D04DE20020A0E1004095E5DE\r
+S3150000D900000054E330A81B198C309FE50400A0E109\r
+S3150000D910002083E53DF4FFEB000050E3000085E5C1\r
+S3150000D9201300000A0400A0E170309FE50222A0E384\r
+S3150000D930002183E7010080E20C0050E3F9FFFFDAE3\r
+S3150000D94000C0A0E30C20A0E10C30A0E10C10A0E187\r
+S3150000D9504C009FE500C08DE504C08DE5AFF3FFEBFD\r
+S3150000D96040309FE50321A0E3002083E530681BE9F2\r
+S3150000D97075FFFFEA30309FE530C09FE5000093E574\r
+S3150000D9802C109FE52C209FE52C309FE500C08DE5EF\r
+S3150000D990B12D00EBAB2900EBB41A0200C01A02004D\r
+S3150000D9A060B10200F0D50000080005809C1202005C\r
+S3150000D9B0D7010000BC0D02002C100200401002002E\r
+S3150000D9C00DC0A0E110D82DE918409FE5003094E580\r
+S3150000D9D0000053E304B04CE210A81B19D7F3FFEB89\r
+S3150000D9E0000084E510A81BE9C41A02000DC0A0E1DE\r
+S3150000D9F0F0DD2DE934A19FE504B04CE204D04DE200\r
+S3150000DA000228A0E100C09AE500005CE30080A0E1E6\r
+S3150000DA100170A0E10360A0E14248A0E13A00000ADB\r
+S3150000DA20040053E308319FE50121A0E3002083E5CC\r
+S3150000DA300C00A011EAF4FF1B0418A0E1F4209FE5F6\r
+S3150000DA402118A0E10138A0E110C082E20040A0E365\r
+S3150000DA50410D83E3023083E3104082E5090080E351\r
+S3150000DA6004308CE5D0309FE508708CE5004082E5F7\r
+S3150000DA70040082E5088082E50C1082E50317A0E326\r
+S3150000DA801C1183E470C083E4782103E40820A0E33A\r
+S3150000DA90042003E4004083E50150A0E34F3F83E206\r
+S3150000DAA07050C3E40050C3E5000056E38C409FE588\r
+S3150000DAB000009A051000000A84309FE5014054E2F8\r
+S3150000DAC0003093E50E00000A080013E30300001A75\r
+S3150000DAD0020056E3F7FFFF1A061800EBF5FFFFEA10\r
+S3150000DAE0040056E3F0AD1B0940309FE5000093E5C6\r
+S3150000DAF044309FE50121A0E3002083E5F06D1BE99A\r
+S3150000DB00E1F4FFEA0000FDFFF4FFFFEA34309FE591\r
+S3150000DB1018C0A0E3000093E52C109FE52C209FE59C\r
+S3150000DB202C309FE500C08DE54B2D00EB452900EB21\r
+S3150000DB30C41A020008400080D00300600440008040\r
+S3150000DB4060E31600104000809C120200BC0D02002B\r
+S3150000DB5098100200AC1002000DC0A0E168309FE5ED\r
+S3150000DB6010D82DE91EE040E204B04CE2932ECCE042\r
+S3150000DB7058409FE5CEEFA0E10F00B4E8CCE06EE0A0\r
+S3150000DB8024C04BE214D04DE28EE08EE00F00ACE8EC\r
+S3150000DB903C109FE5003094E50EE1A0E101008EE027\r
+S3150000DBA00820D0E500308CE5B1E09EE11E204BE573\r
+S3150000DBB0B4E24BE1B400D0E1B0024BE164ECFFEB20\r
+S3150000DBC024004BE26AEDFFEB10A81BE96766666668\r
+S3150000DBD008110200C81A02000DC0A0E130D82DE9D4\r
+S3150000DBE08C109FE58CE09FE504B04CE288509FE5E1\r
+S3150000DBF088C09FE588309FE50341A0E30020A0E3AD\r
+S3150000DC00004081E500208CE500408EE5002085E59A\r
+S3150000DC10004083E56C309FE5004081E500208CE5FF\r
+S3150000DC2000408EE5002085E5012082E2002083E5A4\r
+S3150000DC3054009FE51A0000EB50309FE53F24A0E317\r
+S3150000DC40002083E548309FE51C20A0E3044003E460\r
+S3150000DC50002083E53C309FE51D2042E2002083E55D\r
+S3150000DC600D2C82E2103083E2002083E530681BE948\r
+S3150000DC7052FFFFEA0840008008400180044001800E\r
+S3150000DC80044000800880018040000480FFFF0000FF\r
+S3150000DC901883018008400680188101800EF0A0E1FB\r
+S3150000DCA00EF0A0E10EF0A0E134309FE50020E0E3A5\r
+S3150000DCB0002083E5630050E3043043E20008A0E15E\r
+S3150000DCC0000083E50EF0A081012882E2143083E291\r
+S3150000DCD0002083E56420A0E3043043E2002083E5CE\r
+S3150000DCE00EF0A0E1584006800DC0A0E110D82DE945\r
+S3150000DCF004B04CE2991800EB60009FE5002090E527\r
+S3150000DD005C309FE5012082E20810A0E3001083E565\r
+S3150000DD10002080E50040A0E348309FE5842193E79A\r
+S3150000DD20000052E30400A0E1014084E20600001A6C\r
+S3150000DD30090054E3F7FFFFDA0120A0E34231A0E334\r
+S3150000DD40002083E50300A0E310A81BE90C309FE543\r
+S3150000DD50001093E50FE0A0E102F0A0E1F3FFFFEA77\r
+S3150000DD60841C020008C005800C7F02000DC0A0E1E3\r
+S3150000DD7010D82DE904B04CE20040A0E334309FE512\r
+S3150000DD80843183E0042093E5000052E30400A0E11F\r
+S3150000DD90014084E20200001A090054E310A81BC9DE\r
+S3150000DDA0F5FFFFEA10309FE5001093E50FE0A0E1D4\r
+S3150000DDB002F0A0E1F7FFFFEA0C7F0200841C0200DC\r
+S3150000DDC00DC0A0E130D82DE9BC309FE50321A0E3CA\r
+S3150000DDD004B04CE20CD04DE20050A0E1082083E4F0\r
+S3150000DDE0003093E5023113E20300A00130A81B09BD\r
+S3150000DDF098409FE5400000EB003094E5000053E3B7\r
+S3150000DE001E00000A0000A0E384309FE50010A0E396\r
+S3150000DE10802183E0801183E7010080E2090050E35E\r
+S3150000DE20041082E5F7FFFF9A68C09FE568409FE50A\r
+S3150000DE3000C08DE564C09FE50120A0E160309FE54C\r
+S3150000DE403000A0E310108DE9101800EB000094E5F7\r
+S3150000DE50231800EB4C309FE50420A0E33000A0E33C\r
+S3150000DE60002083E5371800EB000055E30100001A97\r
+S3150000DE700100A0E330A81BE9130000EBFBFFFFEA5B\r
+S3150000DE80AEF2FFEB000084E5DDFFFFEA08C0058087\r
+S3150000DE908C1C02000C7F02006CDD0000087F020073\r
+S3150000DEA0EC7E0200E8DC00002401008004309FE5DF\r
+S3150000DEB0000093E50EF0A0E1841C020004309FE50B\r
+S3150000DEC0000093E50EF0A0E120C0058020309FE51C\r
+S3150000DED00120A0E3002083E518309FE5072082E2B9\r
+S3150000DEE0002083E5062042E2043043E2002083E579\r
+S3150000DEF00EF0A0E1881C020008C005801C209FE5EA\r
+S3150000DF000230A0E3003082E5063083E2003082E58D\r
+S3150000DF100C309FE50020A0E3002083E50EF0A0E191\r
+S3150000DF2008C00580881C020004309FE5000093E5C8\r
+S3150000DF300EF0A0E1881C020034209FE50000A0E35B\r
+S3150000DF4030309FE5803193E7000053E30200001A6A\r
+S3150000DF50003092E5000053E30EF0A001010080E2DC\r
+S3150000DF60090050E3082082E20000E0C30EF0A0C1E1\r
+S3150000DF70F2FFFFEA107F02000C7F02000DC0A0E155\r
+S3150000DF80F0D92DE96C809FE5003098E504B04CE2AD\r
+S3150000DF900060A0E10300A0E10150A0E190F3FFEBD7\r
+S3150000DFA054309FE5004093E5000054E30070E0E341\r
+S3150000DFB00E00001ADFFFFFEB40209FE5010070E333\r
+S3150000DFC0803182E004608315805182170070A011B1\r
+S3150000DFD0000054E30300001A000098E5AAF3FFEBE3\r
+S3150000DFE00700A0E1F0A91BE9B7FFFFEBF9FFFFEA85\r
+S3150000DFF0C1FFFFEBEEFFFFEA8C1C0200881C02004B\r
+S3150000E0000C7F02000DC0A0E1090050E370D82DE995\r
+S3150000E01004B04CE254609FE50050A0E170A81B8953\r
+S3150000E020000096E56EF3FFEB44309FE5004093E574\r
+S3150000E030000054E30B00001A38109FE50020A0E30F\r
+S3150000E040853181E0000054E3042083E5852181E7E2\r
+S3150000E0500200001A000096E570681BE98AF3FFEAE1\r
+S3150000E06099FFFFEBFAFFFFEAA3FFFFEBF1FFFFEAE1\r
+S3150000E0708C1C0200881C02000C7F0200F0452DE972\r
+S3150000E0801C70DDE59CE09FE50338A0E1000057E346\r
+S3150000E0904338A0E102A0A0E18C209FE523C4A0E1C3\r
+S3150000E0A00130CE150230CE050030A0E3FF0000E2BD\r
+S3150000E0B0003082E574309FE5016080E2015080E225\r
+S3150000E0C0FF8001E2083883E10000CE150000CE058E\r
+S3150000E0D00250CE1501C0CE050360CE05000057E301\r
+S3150000E0E0043082E548009FE548309F1548309F057B\r
+S3150000E0F0131888E3043080E508A082E524309FE504\r
+S3150000E1000C1082E5002080E524209FE5000057E3FF\r
+S3150000E110083082E524309F1524309F050E40A0E18B\r
+S3150000E1200C3082E5F085BDE8100400605004006004\r
+S3150000E130CA1000006004006086100200861003000A\r
+S3150000E14002002B0003002B0030402DE90CE0DDE53A\r
+S3150000E1500338A0E100005EE30250A0E1FF0000E208\r
+S3150000E160FF4001E243C8A0E12600000AB4309FE563\r
+S3150000E170012080E201C0C3E50220C3E50000C3E53B\r
+S3150000E180A4109FE50030A0E3A0C09FE5003081E524\r
+S3150000E1909C309FE500005EE398209FE504308CE507\r
+S3150000E1A094309F1594309F05042882E1042081E570\r
+S3150000E1B008308CE574209FE584309FE5210684E3D2\r
+S3150000E1C000005EE3020880E30C3082E5085081E53A\r
+S3150000E1D070309F1570309F050C0081E500108CE5AE\r
+S3150000E1E068109FE50C0081E838309FE55C209FE5CC\r
+S3150000E1F000005EE3083082E554309F1554309F05D9\r
+S3150000E2000C3082E53080BDE818309FE5011080E2D1\r
+S3150000E2102C24A0E10120C3E50310C3E50000C3E5FB\r
+S3150000E22002C0C3E5D5FFFFEA1004006020040060C9\r
+S3150000E2303004006086100100C9100000120400605E\r
+S3150000E2401304006001002B008610020086100300F4\r
+S3150000E2504004006002000B0003000B000DC0A0E1AB\r
+S3150000E26000D82DE904B04CE23C1700EB30209FE5C6\r
+S3150000E27030109FE50830A0E3003082E5003081E5EC\r
+S3150000E2800237A0E3003082E5023743E2003081E541\r
+S3150000E2900120A0E3423183E2002083E50300A0E3EE\r
+S3150000E2A000A81BE9184002801440028004E02DE516\r
+S3150000E2B010309FE5003093E5000053E204F09D0422\r
+S3150000E2C004E09DE4D91700EA901C020040109FE587\r
+S3150000E2D040009FE50830A0E30227A0E3003081E577\r
+S3150000E2E0003080E5002081E52C309FE5002080E5A8\r
+S3150000E2F028209FE5002083E524309FE50020A0E349\r
+S3150000E300002083E51C309FE5062A82E2002083E593\r
+S3150000E3100EF0A0E11840028014400280488005807B\r
+S3150000E320FFFF0000A0B10200448005800DC0A0E1FF\r
+S3150000E33000D82DE904B04CE2081700EB28309FE521\r
+S3150000E340002093E524309FE5002083E520309FE5FB\r
+S3150000E350FF2CA0E3002083E50120A0E34231A0E3E7\r
+S3150000E360002083E50300A0E300A81BE940800580A8\r
+S3150000E370A0B102004880058004E02DE510309FE53D\r
+S3150000E380003093E5000053E204F09D0404E09DE4B0\r
+S3150000E390A61700EA941C02000DC0A0E130D82DE9B2\r
+S3150000E3A004B04CE2B4C09FE50CD04DE20010A0E3EF\r
+S3150000E3B0AC409FE500C08DE5A8C09FE50120A0E127\r
+S3150000E3C0A4309FE51A00A0E310108DE9AF1600EB0C\r
+S3150000E3D0000094E5C21600EB90209FE590109FE5A3\r
+S3150000E3E00830A0E3003082E588509FE5003081E5E3\r
+S3150000E3F00237A0E3003082E50040A0E3013743E2A4\r
+S3150000E400004081E51A00A0E3003085E5CD1600EB5B\r
+S3150000E41064C09FE50410A0E100C08DE55C409FE567\r
+S3150000E4205CC09FE50120A0E158309FE51B00A0E3FA\r
+S3150000E43010108DE9951600EB000094E5A81600EB88\r
+S3150000E44044209FE544309FE51B00A0E3002083E5C0\r
+S3150000E4500133A0E3003085E530681BE9B91600EA10\r
+S3150000E460ACE20000787F02005C7F02005CE2000004\r
+S3150000E4701840028014400280C400008078E3000047\r
+S3150000E480987F02007C7F02002CE30000FFFF000063\r
+S3150000E490488005800311A0E3A221A0E30231A0E396\r
+S3150000E4A004E02DE5003082E5013083E0003082E5AE\r
+S3150000E4B034309FE5522182E2201383E4002083E575\r
+S3150000E4C028309FE528209FE5281083E4002083E577\r
+S3150000E4D04020A0E3183083E2002083E514309FE556\r
+S3150000E4E0001083E504E09DE43E0000EA0880018018\r
+S3150000E4F008800580FE000001084002804C309FE540\r
+S3150000E5000227A0E3002083E5022742E240309FE590\r
+S3150000E510003093E5020713E30200000A012082E2BD\r
+S3150000E520130052E3F8FFFF9A140052E324309F15BC\r
+S3150000E5300010A0130820A013002083150100A003DB\r
+S3150000E540043043120100A011001083150EF0A0E163\r
+S3150000E55004400280004002801840028040209FE56F\r
+S3150000E5600231A0E3003082E538309FE5002093E5D4\r
+S3150000E570032082E22C309FE5003093E5030052E150\r
+S3150000E580FBFFFF8A20309FE50321A0E3002083E5FF\r
+S3150000E59018209FE5283083E2002083E50000A0E3F1\r
+S3150000E5A00EF0A0E104800580B0C0018008800580DF\r
+S3150000E5B0FE00000124309FE54020A0E3002083E513\r
+S3150000E5C02F2042E2183083E2002083E510209FE5E9\r
+S3150000E5D0603043E2002083E50000A0E30EF0A0E1F6\r
+S3150000E5E04880058001001B210DC0A0E100D82DE95F\r
+S3150000E5F004B04CE2C0FFFFEB000050E30100A013A3\r
+S3150000E60000A81B19D4FFFFEB000050E30200A01383\r
+S3150000E61000A81B1984209FE50330D2E5400013E3D0\r
+S3150000E6200300A00300A81B090330D2E5A333B0E121\r
+S3150000E6300400A00300A81B0964309FE51120A0E395\r
+S3150000E640002083E55C209FE5603043E2402083E4C0\r
+S3150000E6500030D3E5400013E30700001AFA0F50E339\r
+S3150000E660010080E20500A08300A81B8938309FE5E1\r
+S3150000E6700030D3E5400013E3F7FFFF0A9EFFFFEBF0\r
+S3150000E680000050E30600A01300A81B19B2FFFFEB21\r
+S3150000E690000050E30700A0130000A00300A81BE938\r
+S3150000E6A0808005806080058001001B2140800580F8\r
+S3150000E6B00DC0A0E110D82DE904B04CE28EFFFFEBAF\r
+S3150000E6C0000050E30040A0E10500000A34309FE559\r
+S3150000E6D0000093E5ECF1FFEB0030A0E30300A0E1BE\r
+S3150000E6E010A81BE99CFFFFEB000050E30130A0E3FC\r
+S3150000E6F0F9FFFF0A0C309FE5000093E5E2F1FFEB1E\r
+S3150000E7000430A0E1F4FFFFEA981C02000DC0A0E16E\r
+S3150000E710F0DD2DE90150A0E10340A0E114319FE5B1\r
+S3150000E72004B04CE204D04DE20558A0E10448A0E153\r
+S3150000E730001093E54558A0E12439A0E10060A0E16E\r
+S3150000E7404448A0E10558A0E10280A0E10470DBE5A1\r
+S3150000E7500100A0E1FF6006E22558A0E1FF4004E2C7\r
+S3150000E76002A083E29EF1FFEB0530A0E10600A0E1E6\r
+S3150000E7700410A0E10820A0E100708DE571FEFFEB1A\r
+S3150000E7800030A0E37AFF17EEFDFFFF1A9A3F07EE6F\r
+S3150000E790173F07EE0040A0E3C4FFFFEB000050E385\r
+S3150000E7A00100A003F0AD1B09C7FEFFEB88309FE513\r
+S3150000E7B088209FE5000093E584309FE5302083E4C0\r
+S3150000E7C00120A0E30020C3E50A10A0E119F2FFEB47\r
+S3150000E7D0000050E36C309F050020930568309F05CC\r
+S3150000E7E00020830560309FE50030D3E5200013E369\r
+S3150000E7F00A10A0E10900000A014084E2090054E37E\r
+S3150000E800E4FFFF9A2C309FE5000093E59EF1FFEBB5\r
+S3150000E810090054E30000A0930100A083F0AD1BE9BA\r
+S3150000E82028309FE5000093E502F2FFEB000050E37D\r
+S3150000E830F0FFFF0AF2FFFFEA981C0200941C020098\r
+S3150000E840400400609041028040800580A0B1020033\r
+S3150000E850901C02000DC0A0E1F0DD2DE90150A0E101\r
+S3150000E8600340A0E110319FE504B04CE204D04DE234\r
+S3150000E8700558A0E10448A0E1001093E54558A0E141\r
+S3150000E8802439A0E10060A0E14448A0E10558A0E1D8\r
+S3150000E8900280A0E10470DBE50100A0E1FF6006E272\r
+S3150000E8A02558A0E1FF4004E202A083E24CF1FFEB11\r
+S3150000E8B00530A0E10600A0E10410A0E10820A0E1D7\r
+S3150000E8C000708DE5ECFDFFEB0030A0E37AFF17EE5C\r
+S3150000E8D0FDFFFF1A9A3F07EE0040A0E373FFFFEB30\r
+S3150000E8E0000050E30100A003F0AD1B0976FEFFEB2C\r
+S3150000E8F088309FE588209FE5000093E584309FE5FA\r
+S3150000E900302083E40120A0E30020C3E50A10A0E143\r
+S3150000E910C8F1FFEB000050E36C309F050020930523\r
+S3150000E92068309F050020830560309FE50030D3E501\r
+S3150000E930200013E30A10A0E10900000A014084E266\r
+S3150000E940090054E3E4FFFF9A2C309FE5000093E5AD\r
+S3150000E9504DF1FFEB090054E30000A0930100A083F2\r
+S3150000E960F0AD1BE928309FE5000093E5B1F1FFEB20\r
+S3150000E970000050E3F0FFFF0AF2FFFFEA981C0200D6\r
+S3150000E980941C020060040060904102804080058073\r
+S3150000E990A0B10200901C02000DC0A0E170D82DE9C4\r
+S3150000E9A094609FE5003096E5000053E304B04CE226\r
+S3150000E9B00100A01370A81B1980409FE5000094E594\r
+S3150000E9C0000050E31900000A74409FE5000094E53A\r
+S3150000E9D0000050E31200000A68509FE5003095E5FC\r
+S3150000E9E0000053E30B00000A000095E5FCF0FFEB86\r
+S3150000E9F068FEFFEBA6FEFFEB000050E30040A0E13F\r
+S3150000EA000130A013000095E5003086151EF1FFEBDE\r
+S3150000EA100400A0E170A81BE9C8EFFFEB000085E544\r
+S3150000EA20F0FFFFEAF9EFFFEB000084E5E9FFFFEAFC\r
+S3150000EA30F6EFFFEB000084E5E2FFFFEA9C1C020014\r
+S3150000EA40901C0200941C0200981C02000DC0A0E15C\r
+S3150000EA50F0D92DE904B04CE204D04DE202C8A0E1A1\r
+S3150000EA604CC8A0E10380A0E10320A0E1F430DBE183\r
+S3150000EA70FFE001E20C18A0E10CC8A0E12C78A0E1AF\r
+S3150000EA8003C8A0E12C58A0E10338A0E1FF0010E381\r
+S3150000EA902368A0E10E00A0E12118A0E10530A0E165\r
+S3150000EAA008C0DBE50040A0E30500000A00C08DE5D4\r
+S3150000EAB067FFFFEB040050E10540A0010400A0E160\r
+S3150000EAC0F0A91BE90E00A0E10710A0E10820A0E1D3\r
+S3150000EAD00630A0E100C08DE50BFFFFEB000050E320\r
+S3150000EAE00640A0010040A013F3FFFFEA0DC0A0E11D\r
+S3150000EAF00118A0E1F0DF2DE94168A0E104B04CE285\r
+S3150000EB0006C8A0E12C1BA0E1011366E0401081E2DB\r
+S3150000EB100118A0E108D04DE20338A0E14158B0E168\r
+S3150000EB200270A0E1FFA000E24348A0E10490DBE50B\r
+S3150000EB300080A0E32C28A0E11200000A0438A0E11E\r
+S3150000EB40230855E14358A0C105C8A0E10730A0E15C\r
+S3150000EB502CC8A0E10100A0E30A10A0E100C08DE5E9\r
+S3150000EB6004908DE5B8FFFFEB063085E0042065E0F4\r
+S3150000EB700338A0E10228A0E10080A0E14368A0E1FB\r
+S3150000EB804248A0E1057087E00438A0E1000058E3A0\r
+S3150000EB90000053132338A0E10400000A400053E3A9\r
+S3150000EBA00E00008A0438A0E123C8B0E10100001A73\r
+S3150000EBB00800A0E1F0AF1BE90628A0E12228A0E1A9\r
+S3150000EBC00A10A0E10730A0E10100A0E300C08DE536\r
+S3150000EBD004908DE59CFFFFEB000088E0F0AF1BE999\r
+S3150000EBE00628A0E10730A0E12228A0E140C0A0E36A\r
+S3150000EBF00100A0E30A10A0E100C08DE504908DE5B8\r
+S3150000EC0091FFFFEB402044E2403086E20228A0E17B\r
+S3150000EC100338A0E1000050E34368A0E1407087E2BA\r
+S3150000EC204248A0E1E1FFFF0A010552E3008088E0C7\r
+S3150000EC30EAFFFF8ADAFFFFEA0DC0A0E10118A0E1B2\r
+S3150000EC40F0DF2DE94168A0E104B04CE206C8A0E17E\r
+S3150000EC502C1BA0E1011366E0401081E20118A0E13F\r
+S3150000EC6008D04DE20338A0E14158B0E10270A0E1BE\r
+S3150000EC70FFA000E24348A0E10490DBE50080A0E3AA\r
+S3150000EC802C28A0E11200000A0438A0E1230855E16F\r
+S3150000EC904358A0C105C8A0E10730A0E12CC8A0E1F7\r
+S3150000ECA00800A0E10A10A0E100C08DE504908DE502\r
+S3150000ECB065FFFFEB063085E0042065E00338A0E140\r
+S3150000ECC00228A0E10080A0E14368A0E14248A0E15B\r
+S3150000ECD0057087E00438A0E1000058E300005313F4\r
+S3150000ECE02338A0E10400000A400053E30E00008A26\r
+S3150000ECF00438A0E123C8B0E10100001A0800A0E131\r
+S3150000ED00F0AF1BE90628A0E12228A0E10A10A0E145\r
+S3150000ED100730A0E10000A0E300C08DE504908DE57A\r
+S3150000ED2049FFFFEB000088E0F0AF1BE90628A0E1F1\r
+S3150000ED300730A0E12228A0E140C0A0E30000A0E344\r
+S3150000ED400A10A0E100C08DE504908DE53EFFFFEBC3\r
+S3150000ED50402044E2403086E20228A0E10338A0E1E8\r
+S3150000ED60000050E34368A0E1407087E24248A0E11A\r
+S3150000ED70E1FFFF0A010552E3008088E0EAFFFF8A0F\r
+S3150000ED80DAFFFFEA28209FE50010A0E30330A0E3A6\r
+S3150000ED901C1082E5203082E514309FE5010183E7EF\r
+S3150000EDA0011081E2050051E3020A80E20EF0A0C1E3\r
+S3150000EDB0F8FFFFEAC0B102000030A0E37AFF17EEC9\r
+S3150000EDC0FDFFFF1A9A3F07EE34109FE51C2091E5E0\r
+S3150000EDD01C3091E5013083E21C3081E51C3091E561\r
+S3150000EDE000C0A0E3050053E3020191E71CC0818542\r
+S3150000EDF07AFF17EEFDFFFF1A0030A0E39A3F07EEF9\r
+S3150000EE000EF0A0E1C0B102000DC0A0E110D82DE9BE\r
+S3150000EE100010A0E104B04CE20030A0E37AFF17EE48\r
+S3150000EE20FDFFFF1A9A3F07EE30409FE5203094E53C\r
+S3150000EE30022AA0E3030194E70130A0E3EAFAFFEB1C\r
+S3150000EE40203094E5013083E2203084E5203094E5DB\r
+S3150000EE50050053E30030A0832030848510A81BE909\r
+S3150000EE60C0B102000DC0A0E100D82DE904B04CE20B\r
+S3150000EE703A1400EB0120A0E34231A0E3002083E531\r
+S3150000EE800300A0E300A81BE90EF0A0E10DC0A0E17D\r
+S3150000EE9000D82DE904B04CE2301400EB30109FE5A9\r
+S3150000EEA030009FE50236A0E3003081E52020A0E394\r
+S3150000EEB0023643E2003080E5002081E5423183E2FC\r
+S3150000EEC0002080E51F2042E2002083E50300A0E346\r
+S3150000EED000A81BE918400280144002800DC0A0E182\r
+S3150000EEE000D82DE928309FE5000093E5000050E3A7\r
+S3150000EEF004B04CE20400001A18209FE50236A0E395\r
+S3150000EF00043002E4003082E500A81BE9C71400EBD8\r
+S3150000EF10F8FFFFEAA81C0200184002802C309FE58B\r
+S3150000EF20000093E5000050E30EF0A00120309FE5BD\r
+S3150000EF30003093E51C309FE51C209FE5003093E5EB\r
+S3150000EF40033062E0FF0EC3E30F00C0E30EF0A0E162\r
+S3150000EF50A41C0200C042028090420280700400603D\r
+S3150000EF6000009FE50EF0A0E17004006084C09FE5FC\r
+S3150000EF7084209FE584309FE5D202A0E3021A8CE24A\r
+S3150000EF80081083E5002083E5040083E5003082E570\r
+S3150000EF90011082E90030A0E37AFF17EEFDFFFF1AA9\r
+S3150000EFA09A3F07EE58009FE558C09FE558309FE509\r
+S3150000EFB00226A0E32010A0E3002083E5001080E5F0\r
+S3150000EFC000108CE5002080E500208CE52C209FE5D4\r
+S3150000EFD09B3F83E2002083E50120A0E3303083E2FB\r
+S3150000EFE00020C3E50030A0E37AFF17EEFDFFFF1A0D\r
+S3150000EFF09A3F07EE0EF0A0E1700400607004016015\r
+S3150000F000800401601840028014400280044002809F\r
+S3150000F0100DC0A0E100D82DE904B04CE220309FE5F8\r
+S3150000F020000093E5D9EFFFEBBBFFFFEB0030A0E15B\r
+S3150000F030020A53E30C009FE50C009F3571FFFFEBBE\r
+S3150000F040F5FFFFEAA81C020070040060702400604F\r
+S3150000F0500DC0A0E170D82DE9B4309FE504B04CE2B4\r
+S3150000F0600CD04DE2AC509FE5004093E5000054E221\r
+S3150000F070A4609FE570A81B1964EEFFEB9C309FE52A\r
+S3150000F0800020A0E1002083E50410A0E10420A0E117\r
+S3150000F0900430A0E188009FE500408DE504408DE541\r
+S3150000F0A0DEEDFFEB7CC09FE500C08DE578C09FE5F7\r
+S3150000F0B00410A0E10420A0E170309FE53100A0E338\r
+S3150000F0C020108DE9711300EB000095E5841300EB29\r
+S3150000F0D05CC09FE500C08DE558C09FE50420A0E117\r
+S3150000F0E00410A0E150309FE53200A0E340108DE906\r
+S3150000F0F0661300EB000096E5791300EB3C309FE5C4\r
+S3150000F100012BA0E33100A0E3002083E570681BE932\r
+S3150000F1108C1300EAAC1C0200B87F0200D87F020004\r
+S3150000F120A81C020010F00000DCEE00009C7F02002C\r
+S3150000F1308CEE000088EE0000BC7F020064EE00004A\r
+S3150000F1402401008004E02DE510309FE5003093E5B2\r
+S3150000F150000053E204F09D0404E09DE48BEFFFEA17\r
+S3150000F160A81C02000DC0A0E110D82DE9CC309FE507\r
+S3150000F170004093E5000054E304B04CE20400000AAA\r
+S3150000F1800030A0E37AFF17EEFDFFFF1A9A3F07EE65\r
+S3150000F19010A81BE9A8009FE5F9FEFFEB0129A0E3F3\r
+S3150000F1A0A0009FE50410A0E1BE1100EB98209FE5AA\r
+S3150000F1B00231A0E3043002E4003082E56330A0E3CC\r
+S3150000F1C00000A0E1013053E2FCFFFF5A78209FE5E2\r
+S3150000F1D00131A0E3043002E4003082E56330A0E3AD\r
+S3150000F1E00000A0E1013053E2FCFFFF5A5EFFFFEB97\r
+S3150000F1F058309FE50228A0E3002083E50000A0E345\r
+S3150000F200403083E2000083E50E20A0E3383043E27D\r
+S3150000F210002083E538109FE538309FE5003081E512\r
+S3150000F2200232A0E3003081E52C309FE5000083E543\r
+S3150000F23008309FE50D2042E2002083E5CFFFFFEA7C\r
+S3150000F240A41C02007044006070040060084007803F\r
+S3150000F250004007800440078001800000A01C0200D7\r
+S3150000F26094309FE5003093E5010053E30400000A63\r
+S3150000F2700030A0E37AFF17EEFDFFFF1A9A3F07EE74\r
+S3150000F2800EF0A0E174209FE574309FE5003082E522\r
+S3150000F2900232A0E3003082E568309FE50211A0E368\r
+S3150000F2A0001082E5001083E56330A0E30000A0E1D2\r
+S3150000F2B0013053E2FCFFFF5A40209FE50131A0E3F5\r
+S3150000F2C0043002E4003082E56330A0E30000A0E1F0\r
+S3150000F2D0013053E2FCFFFF5A2C309FE50226A0E3E3\r
+S3150000F2E0002083E510309FE50010A0E3001083E5C1\r
+S3150000F2F018309FE5001083E5DCFFFFEAA41C02003E\r
+S3150000F3000840078001800000044007800440028016\r
+S3150000F310A01C020004309FE5000093E50EF0A0E17A\r
+S3150000F320A41C0200F0472DE92221A0E13CD04DE2C9\r
+S3150000F33000208DE500309DE50020A0E3030052E1AA\r
+S3150000F34030208DE538008DE534108DE5EE02002A7B\r
+S3150000F350543F9FE5544F9FE5F010D3E1503F9FE5A2\r
+S3150000F360F000D3E1F030D4E1930101E0448F9FE552\r
+S3150000F370F020D8E1403F9FE5900202E0F030D3E173\r
+S3150000F38024308DE5343F9FE538909DE5F030D3E19C\r
+S3150000F390F2C0D9E01C308DE524309DE58110A0E156\r
+S3150000F3A09C1323E0F200D9E01C409DE58220A0E1F9\r
+S3150000F3B0902424E020308DE5043F9FE5F0A0D3E1C2\r
+S3150000F3C0003F9FE5F030D3E1FC8E9FE514308DE5DC\r
+S3150000F3D0F83E9FE518408DE5F020D8E1F0E0D3E156\r
+S3150000F3E038908DE5E83E9FE5E89E9FE5E84E9FE56F\r
+S3150000F3F0E88E9FE5F050D3E1F010D9E1F030D4E18A\r
+S3150000F40024909DE5F040D8E120809DE5D07E9FE5E3\r
+S3150000F410998222E018808DE2000398E8C46E9FE589\r
+S3150000F420998121E02CC08DE514909DE5F0C0D7E1CF\r
+S3150000F43028008DE5990C0CE0F000D6E1930E0EE065\r
+S3150000F440940503E09A0000E08C1041E0011063E0AF\r
+S3150000F450603E9FE5802042E002206EE04CCE9FE5B4\r
+S3150000F460B0E0D3E1803E9FE5B000DCE1B040D7E1FB\r
+S3150000F470B0C0D6E1001083E538909DE5F280D9E072\r
+S3150000F480283E9FE538908DE52C909DE5B090C3E130\r
+S3150000F490203E9FE528909DE5B090C3E14C3E9FE558\r
+S3150000F4A0C227A0E1B020C3E1443E9FE5C157A0E1D9\r
+S3150000F4B0B050C3E13C3E9FE5003093E5000053E3C6\r
+S3150000F4C0B020C6E1302E9F050538A001B020D2013C\r
+S3150000F4D04338A00192030300203E9F151C2E9F0572\r
+S3150000F4E0C337A001B030C201B050C311103E9FE532\r
+S3150000F4F0D41D9FE5003093E5B000C1E1000053E361\r
+S3150000F500D01D9FE5F43D9F15B0E0C1E10010A013AA\r
+S3150000F510C40D9FE5B010C311E83D9FE5B0C0C0E142\r
+S3150000F520003093E538009DE5B0CD9FE5020080E20E\r
+S3150000F530000053E3B040CCE1B050C7E138008DE5A0\r
+S3150000F5409304001AC03D9FE5B020D3E19C3D9FE5A2\r
+S3150000F550F000D3E1A43D9FE5F030D3E1930201E052\r
+S3150000F560900203E0742F9FE5C337A0E1B030C2E1FB\r
+S3150000F570703F9FE5C117A0E1B010C3E15C6F9FE546\r
+S3150000F580607F9FE5F030D6E1F000D7E1031060E040\r
+S3150000F590003083E0A33F83E0702D9FE5C340A0E1E8\r
+S3150000F5A06C3D9FE5002092E5A11F81E0B040C3E1DC\r
+S3150000F5B0603D9FE5C150A0E1000052E3B050C3E1B9\r
+S3150000F5C07004001A50CD9FE550ED9FE500109CE5B4\r
+S3150000F5D000009EE50438A0E10528A0E1433881E05B\r
+S3150000F5E0422880E0413443E0402442E0431444E0B2\r
+S3150000F5F0420445E0B010C6E1B000C7E100308CE53A\r
+S3150000F60000208EE5180D9FE5183D9FE5001093E557\r
+S3150000F610003090E5030051E10C3D9F150120A01339\r
+S3150000F6200020831500CD9FE500309CE5000053E3E4\r
+S3150000F630001080E50A00000A000051E34504001AA4\r
+S3150000F6408C0E9FE58C3E9FE5B020D3E1B030D0E133\r
+S3150000F650033062E0020913E3B030C0E100108C15FC\r
+S3150000F660B010C011681E9FE5703E9FE5F020D3E103\r
+S3150000F670F030D1E1920303E034209DE5C337A0E1E9\r
+S3150000F680B230C2E05C3E9FE534208DE5F030D3E138\r
+S3150000F690F020D1E1920303E030408DE2100294E8BD\r
+S3150000F6A0C337A0E1B230C9E0070014E334908DE51A\r
+S3150000F6B00F02001A743C9FE50828A0E1A22AA0E1E7\r
+S3150000F6C01F1008E21201A0E164CC9FE5B020C3E15F\r
+S3150000F6D0603C9FE5010650E3B010C3E100008CE5F5\r
+S3150000F6E0E83D9F2514C0A0233800002A020750E3F6\r
+S3150000F6F0D83D9F251300A023F803002A010750E3F5\r
+S3150000F700C83D9F251210A023FA03002A020850E3E1\r
+S3150000F710B83D9F251120A023FC03002A010850E3D1\r
+S3150000F720A83D9F251040A023FE03002A020950E3AE\r
+S3150000F730983D9F250F80A0230204002A010950E36B\r
+S3150000F740883D9F250E90A0230004002A020A50E35C\r
+S3150000F750783D9F250DC0A0231C00002A010A50E316\r
+S3150000F760683D9F250C00A023DC03002A020B50E312\r
+S3150000F770583D9F250B10A023DE03002A00309CE590\r
+S3150000F780010B53E3443D9F250A20A023DF03002AF3\r
+S3150000F790020C53E3343D9F250940A023E103002AD0\r
+S3150000F7A0FF0053E3243D9F850880A083E503008A7C\r
+S3150000F7B07F0053E3143D9F850790A083E303008AEF\r
+S3150000F7C03F0053E3C103009A003D9FE506C0A0E356\r
+S3150000F7D0B0C0C3E1583B9FE5004093E5EC3C9FE594\r
+S3150000F7E0B020D3E1841084E0823082E0313283E0BD\r
+S3150000F7F0033043E2409B9FE5020913E300C0A013D8\r
+S3150000F800B030C9E1B0C0C911300B9FE5B0C0D9E135\r
+S3150000F810B030D0E101C08CE2247B9FE50C0083E090\r
+S3150000F820206B9FE5A30140E0B050D7E1183B9FE570\r
+S3150000F8302442A0E1B010D6E10028A0E1B0E0D3E177\r
+S3150000F840853044E0031081E0A2A9A0E1FC3A9FE5DF\r
+S3150000F8500A24A0E1B020C3E1F43A9FE5B010C3E169\r
+S3150000F860F03A9FE5D41A9FE5B0A0C3E1E83A9FE5D8\r
+S3150000F87000005EE3B050C6E1B040C7E1B0C0C9E1E8\r
+S3150000F880B000C1E1B040C3E18F01001ACC3A9FE558\r
+S3150000F8900A2CA0E1B000D3E12218A0E1000051E15A\r
+S3150000F8A0BC3A9F85BC3A9F95B020D3E1FF3C62E20B\r
+S3150000F8B0FF3083E2910303E0903222E0901A9FE545\r
+S3150000F8C0A43A9FE5A04A9FE5002083E5F030D1E108\r
+S3150000F8D0B220D4E1000053E3803A9FE5B020C3E1B3\r
+S3150000F8E0883A9FE5B020C3E1B030D1E1003063B281\r
+S3150000F8F0B030C1B1782A9FE5B030D1E1B020D2E175\r
+S3150000F900033062E06C2A9FE5020913E3B030C2E1DE\r
+S3150000F9100030A013B030C2115C0A9FE5B020D2E1DE\r
+S3150000F920B030D0E1022083E0A32142E04C3A9FE5CB\r
+S3150000F9300218A0E1B0E0D3E1A119A0E1403A9FE5A9\r
+S3150000F9400E0051E1B010C3E1383A9F85383A9F95D1\r
+S3150000F950B020C0E1B020D3E1FF3C62E201C0A0E1EB\r
+S3150000F960FF3083E29C0303E09E3223E0003084E50F\r
+S3150000F9700C3A9FE5F0C99FE5B010D3E10C3A9FE53C\r
+S3150000F980B220DCE1B000D3E1F0399FE5B020C3E15D\r
+S3150000F990FC399FE5000051E1B020C3E1F4399F85B1\r
+S3150000F9A0F4399F95B020D3E1FF3C62E2FF3083E259\r
+S3150000F9B0910303E0903223E000308CE5DC399FE5CB\r
+S3150000F9C0B020D3E1C8399FE5B030D3E1930202E01D\r
+S3150000F9D0CC399FE5B010D3E190399FE5B0C0D3E1B3\r
+S3150000F9E084399FE51221A0E1B210D3E1B4399FE535\r
+S3150000F9F0B010C3E194399FE5B010C3E1A8399FE583\r
+S3150000FA00B030D3E1910303E0A0099FE5C2274CE0A3\r
+S3150000FA10020912E3B020C0E194299FE5B020D2E1AB\r
+S3150000FA201332A0E18C299FE5C3374CE00040A013B8\r
+S3150000FA30B030C2E1B040C011020913E378399FE546\r
+S3150000FA40F010D0E1B030D3E10080A013B080C21135\r
+S3150000FA50030051E164299FD50E0000DA60399FE565\r
+S3150000FA60B000D3E1000051E158399FB5B020D3B1C1\r
+S3150000FA70003061B0930201B04C399FB5B020D3B1CC\r
+S3150000FA8048399FB5513243B044299FB5B030C2B111\r
+S3150000FA90020000BA34299FE534399FE5B020C3E15E\r
+S3150000FAA030399FE5003093E5000053E31700001A54\r
+S3150000FAB000399FE5F010D3E11C399FE5B030D3E162\r
+S3150000FAC0030051E1F4289FD50E0000DA0C399FE5BA\r
+S3150000FAD0B000D3E1000051E104399FB5B020D3B1A5\r
+S3150000FAE0003061B0930201B0F8389FB5B020D3B1B1\r
+S3150000FAF0D8389FB5513243B0EC289FB5B030C2B16B\r
+S3150000FB00020000BAC4289FE5DC389FE5B020C3E1B7\r
+S3150000FB10A0389FE5D110D3E1D0389FE5B020D3E1DE\r
+S3150000FB20022061E0020912E3D0079FE50090A013CE\r
+S3150000FB30B020C0E1B8389FE5B090C011B010C3E165\r
+S3150000FB40B030D0E1143063E2020913E38C299FE55B\r
+S3150000FB5000C0A013B030C2E1B0C0C211F020D2E1A3\r
+S3150000FB600E0052E3823282C088289FC5832182C05C\r
+S3150000FB70050000CA090052E3C70200DA023182E03A\r
+S3150000FB8074289FE5033383E0832082E054399FE5A0\r
+S3150000FB90B020C3E14CC99FE5B030DCE158279FE5B2\r
+S3150000FBA0020913E3B030C2E10239E013B030C211EA\r
+S3150000FBB0F8379FE5D110D3E140389FE5B020D3E177\r
+S3150000FBC03C389FE5022061E0020912E32C079FE51D\r
+S3150000FBD0B010C3E10010A013B020C0E1B010C011F6\r
+S3150000FBE0B030D0E1F4289FE5143063E2020913E354\r
+S3150000FBF0B030C2E10030A013B030C211F030D2E113\r
+S3150000FC00100053E3833183C0503043C2090000CA59\r
+S3150000FC100C0053E3833083C08330A0C1213043C23C\r
+S3150000FC20040000CA080053E30331A0C18330A0D109\r
+S3150000FC30083043C2093083D2B030CCE1A4389FE506\r
+S3150000FC40F030D3E1032183E0BC169FE5823183E0E7\r
+S3150000FC50010A13E38331A0E1B030C1E10239E013B8\r
+S3150000FC60B030C1119C379FE5B020D1E1030052E1CD\r
+S3150000FC7001308392B030C1918C379FE5003093E517\r
+S3150000FC80000053E39000001A48379FE5002093E5F3\r
+S3150000FC90010052E378369F0574369F150240A01383\r
+S3150000FCA0B020C301B040C31164369FE5F020D3E114\r
+S3150000FCB048169FE50030A0E3020053E1B030C1E1F1\r
+S3150000FCC07D0000AAF030D1E1000053E300279F0534\r
+S3150000FCD014279F1504389FE5B020D2E1B020C3E178\r
+S3150000FCE0F8379FE5F020D3E120379FE5030052E186\r
+S3150000FCF0D70000CA18279FE5CC379FE5B020C3E19F\r
+S3150000FD00BC379FE50D2042E2B020C3E104279FE502\r
+S3150000FD1074379FE5B020C3E190379FE50110A0E35B\r
+S3150000FD2098279FE5B010C3E164379FE5B020C3E193\r
+S3150000FD306C279FE55C379FE5B020C3E1D8269FE599\r
+S3150000FD4074379FE5B020C3E15C379FE5CC269FE57D\r
+S3150000FD50B020C3E158379FE50200A0E3B000C3E13D\r
+S3150000FD6060379FE58A8EE0E3B080C3E144379FE5C4\r
+S3150000FD70B010C3E120379FE5B000C3E17C359FE5B5\r
+S3150000FD80F030D3E1000053E37200001A4C379FE5D0\r
+S3150000FD90F010D3E1813361E0033161E0031181E0CA\r
+S3150000FDA014379FE5F0E0D3E11C379FE5F0C0D3E1BF\r
+S3150000FDB00C379FE5011161E0F000D3E18111A0E16C\r
+S3150000FDC0CC369FE5C117A0E1F030D3E10128A0E1D0\r
+S3150000FDD02228A0E1920306E0E8369FE5920005E0BE\r
+S3150000FDE0F000D3E1A0369FE5920E07E0920C04E006\r
+S3150000FDF0F0E0D3E19C369FE5F0C0D3E1A8369FE55D\r
+S3150000FE00F020D3E1AC369FE5B090D3E19C369FE578\r
+S3150000FE10B030D3E110308DE57C369FE5B0A0D3E15C\r
+S3150000FE208C369FE5B030D3E18440A0E1C777A0E1EE\r
+S3150000FE300C308DE5440880E00738A0E1432882E0D5\r
+S3150000FE408550A0E110309DE5990000E045E88EE080\r
+S3150000FE50930E0EE08660A0E146C88CE09A0C0CE09A\r
+S3150000FE600C409DE5940202E04C349FE5B000C3E1EE\r
+S3150000FE7034349FE5B0E0C3E144349FE5B0C0C3E14C\r
+S3150000FE8048349FE5B020C3E194359FE5B010C3E147\r
+S3150000FE9050369FE564149FE5B070C3E1B020D1E110\r
+S3150000FEA06C349FE5012082E2F000D3E10238A0E144\r
+S3150000FEB0430850E1B020C1E181FFFFCA14359FE538\r
+S3150000FEC0003093E5010053E31100000A78049FE532\r
+S3150000FED0B020D0E14C359FE5012082E293C2C1E01B\r
+S3150000FEE0C23FA0E1413163E0033183E0832042E079\r
+S3150000FEF0B020C0E130009DE500109DE5010080E2E4\r
+S3150000FF00010050E130008DE510FDFF3A3CD08DE256\r
+S3150000FF10F087BDE8A0239FE5A0339FE5B020D2E19E\r
+S3150000FF20B020C3E180239FE584339FE5B020D2E172\r
+S3150000FF30B020C3E188239FE588339FE5B020D2E156\r
+S3150000FF40B020C3E184239FE584339FE5B020D2E14E\r
+S3150000FF50B020C3E1DCFFFFEA80359FE5F010D3E176\r
+S3150000FF60813361E0033161E0031181E048359FE5AB\r
+S3150000FF70F0E0D3E150359FE5011161E0F0C0D3E137\r
+S3150000FF803C359FE58111A0E1F000D3E1C117A0E166\r
+S3150000FF90FC349FE50128A0E12228A0E1F030D3E15E\r
+S3150000FFA0920C04E0920306E018359FE5920005E006\r
+S3150000FFB0F000D3E1D0349FE5920E07E0F0E0D3E104\r
+S3150000FFC0D0349FE5F0C0D3E1DC349FE5F020D3E1E7\r
+S3150000FFD0E0349FE5B080D3E1D0349FE5B030D3E183\r
+S3150000FFE008308DE5B0349FE58440A0E1B0A0D3E1B0\r
+S3150000FFF0440880E0B8349FE5980000E08550A0E111\r
+S3150001000008809DE5B030D3E145E88EE08660A0E149\r
+S31500010010980E0EE004308DE5C777A0E146C88CE066\r
+S315000100200738A0E19A0C0CE004909DE5432882E094\r
+S31500010030990202E084329FE5B000C3E170329FE588\r
+S31500010040B0E0C3E17C329FE5B0C0C3E180329FE5F9\r
+S315000100508BFFFFEA7D0D52E3220000AAB0239FE544\r
+S3150001006064349FE5B020C3E154349FE50D2042E29C\r
+S31500010070B020C3E19C239FE50C349FE5B020C3E18A\r
+S3150001008038249FE508349FE5B020C3E110249FE59D\r
+S3150001009000349FE5B020C3E18C239FE518349FE52A\r
+S315000100A0B020C3E100349FE580239FE5B020C3E182\r
+S315000100B0FC339FE50110A0E3B010C3E104349FE5D2\r
+S315000100C08A9EE0E3B090C3E1E8339FE5B010C3E157\r
+S315000100D0D8339FE5B010C3E1BC339FE502C0A0E36E\r
+S315000100E0B0C0C3E124FFFFEA44339FE5030052E1B8\r
+S315000100F0210000CA3C239FE5CC339FE5B020C3E134\r
+S3150001010034239FE5BC339FE5B020C3E12C239FE553\r
+S31500010110AC339FE5B020C3E124239FE568339FE517\r
+S31500010120B020C3E194239FE564339FE5B020C3E18A\r
+S315000101306C239FE55C339FE5B020C3E178339FE5EF\r
+S31500010140DD2F82E2B020C3E15C339FE5F4229FE517\r
+S31500010150B020C3E158339FE50110A0E3B010C3E11D\r
+S3150001016050339FE5B010C3E140339FE5B010C3E1C2\r
+S3150001017024339FE50200A0E3FEFEFFEAC8329FE5B5\r
+S31500010180030052E1220000CAA8229FE538339FE509\r
+S31500010190B020C3E1A0229FE528339FE5B020C3E14B\r
+S315000101A098229FE518339FE5B020C3E190229FE591\r
+S315000101B0D4329FE5B020C3E100239FE5D0329FE50D\r
+S315000101C0B020C3E1D8229FE5C8329FE5B020C3E144\r
+S315000101D078229FE5D0329FE5B020C3E1D0329FE57A\r
+S315000101E00110A0E3B010C3E1C8329FE5B010C3E12E\r
+S315000101F0B8329FE5B010C3E19C329FE50210A0E33F\r
+S31500010200B010C3E1B0329FE5B420E0E3B020C3E112\r
+S31500010210D9FEFFEA38329FE5030052E1B20000CA77\r
+S3150001022038229FE5A0329FE5B020C3E130229FE549\r
+S3150001023090329FE5B020C3E134229FE580329FE5ED\r
+S31500010240B020C3E120229FE53C329FE5B020C3E107\r
+S3150001025068229FE538329FE5B020C3E140229FE541\r
+S3150001026030329FE5B020C3E12C329FE50210A0E3B6\r
+S31500010270E0219FE5B010C3E13C329FE5B020C3E128\r
+S3150001028024329FE5D0219FE5B020C3E124329FE5CA\r
+S31500010290B010C3E114329FE5B010C3E110329FE5FF\r
+S315000102A00140A0E3B040C3E1B3FEFFEA24800200AF\r
+S315000102B0328002002C8002003A8002002280020075\r
+S315000102C02A800200268002002E800200348002006D\r
+S315000102D028800200308002003C8002003880020043\r
+S315000102E0408002003E8002003680020074800200D7\r
+S315000102F04280020044800200B88002001C80020095\r
+S3150001030078800200B4800200BC8002001A800200DC\r
+S31500010310C48002007E80020080800200DC7F020031\r
+S31500010320E07F020068800200648002006C800200A7\r
+S31500010330EE7F0200E47F0200F07F0200E87F020008\r
+S31500010340EA7F0200FE7F020000800200FA7F0200BF\r
+S31500010350F47F020002800200EC7F0200FC7F0200B3\r
+S31500010360F87F020082800200848002007080020011\r
+S31500010370F67F02008E8002001080020004800200D7\r
+S315000103800A80020006800200868002008880020040\r
+S315000103900E800200088002008A8002008C80020022\r
+S315000103A090800200948002000C800200928002007C\r
+S315000103B012800200968002001480020098800200DA\r
+S315000103C0881300009A800200A4800200A680020021\r
+S315000103D06842000016800200B08002009C80020084\r
+S315000103E09E800200A8800200AA80020018800200F6\r
+S315000103F0A28002001E8002005F6B0000BC54000058\r
+S31500010400A080020020800200CC0C0000C080020007\r
+S315000104106F1700005656000063F7FFFFA89FFFFF06\r
+S31500010420B22D00005E800200676666660186FFFFE8\r
+S31500010430244800000F270000116F000066EEFFFF41\r
+S315000104402E6F000018EEFFFFDF300000DF2E0000E8\r
+S31500010450F3160000AF3600002B380000ECF7FFFF63\r
+S31500010460734700008AEEFFFF5F7800000BEEFFFF87\r
+S315000104704F4600001D4800001F640000A3CAFFFF8D\r
+S31500010480A460000040DCFFFF9A6000004C8002007F\r
+S315000104904ADCFFFF568002005280020054800200AF\r
+S315000104A0B64B0000B1C2FFFF69D0FFFF58800200C2\r
+S315000104B04E8002005A800200488002005C800200E1\r
+S315000104C09E7B000050800200468002004A800200A6\r
+S315000104D0F27F020060800200C880020042800200B2\r
+S315000104E07A800200788002007C800200FA0D52E3D5\r
+S315000104F0220000AA9C201FE534301FE5B020C3E18D\r
+S31500010500A4201FE544301FE5B020C3E1A0201FE56C\r
+S3150001051054301FE5B020C3E1B4201FE598301FE534\r
+S31500010520B020C3E16C201FE59C301FE5B020C3E17C\r
+S3150001053094201FE5A4301FE5B020C3E1A8301FE5D4\r
+S315000105400210A0E3B010C3E1E8201FE598301FE5D3\r
+S31500010550B020C3E1A4301FE5B010C3E1B4301FE5FC\r
+S31500010560B010C3E1C0301FE5C38DE0E3B080C3E145\r
+S31500010570C4301FE50190A0E3B090C3E1FEFDFFEAA0\r
+S3150001058018311FE5030052E1210000CA14211FE5BD\r
+S31500010590CC301FE5B020C3E11C211FE5DC301FE58F\r
+S315000105A0B020C3E124211FE5EC301FE5B020C3E1F3\r
+S315000105B028211FE530311FE5B020C3E104211FE5E5\r
+S315000105C034311FE5B020C3E12C211FE53C311FE585\r
+S315000105D0B020C3E164211FE524311FE5B020C3E14A\r
+S315000105E03C311FE570211FE5B020C3E140311FE515\r
+S315000105F00210A0E3B010C3E148311FE5B010C3E11A\r
+S3150001060058311FE5B010C3E174311FE5B010C3E1E5\r
+S31500010610D9FDFFEA9C211FE554311FE5B020C3E156\r
+S31500010620A4211FE564311FE5B020C3E1AC211FE51C\r
+S3150001063074311FE5B020C3E1B0211FE5B8311FE5D4\r
+S31500010640B020C3E18C211FE5BC311FE5B020C3E119\r
+S31500010650B4211FE5C4311FE5B020C3E1C8311FE550\r
+S315000106600210A0E3CC211FE5B010C3E1B8311FE5AC\r
+S31500010670B020C3E1D0311FE5D8211FE5B020C3E189\r
+S31500010680D0311FE5B010C3E1E0311FE5B010C3E181\r
+S31500010690E4311FE504C0A0E390FEFFEA040052E343\r
+S315000106A0823162C0823262D0033283C0833182D00A\r
+S315000106B0033262C0033263D08F3D83C2023083D0DE\r
+S315000106C0E0211FE50E3083C2B030C2E130FDFFEA02\r
+S315000106D01F0053E30300009A10321FE50500A0E353\r
+S315000106E0B000C3E13AFCFFEA0F0053E30300009AAE\r
+S315000106F028321FE50410A0E3B010C3E134FCFFEA81\r
+S31500010700070053E30300009A40321FE50320A0E3EC\r
+S31500010710B020C3E12EFCFFEA030053E30300009A75\r
+S3150001072058321FE50240A0E3B040C3E128FCFFEACE\r
+S31500010730010053E36C321F950090A0930300009AC9\r
+S3150001074078321FE50180A0E3B080C3E120FCFFEA17\r
+S31500010750B090C3E11EFCFFEA8C121FE58C321FE547\r
+S31500010760B020D3E1B030D1E1023083E0020913E3D6\r
+S31500010770B030C1E10239E013B030C1110030A0132D\r
+S3150001078000308C15B6FBFFEAB040C6E1B050C7E1B8\r
+S315000107909BFBFFEAC0221FE5C0321FE5B020D2E174\r
+S315000107A0B020C3E1C8221FE5C8321FE5B020D2E15F\r
+S315000107B0B020C3E170FBFFEA58239FE50030A0E3B8\r
+S315000107C0F0402DE9B030C2E14C239FE5B030C2E1E3\r
+S315000107D048239FE5003082E544239FE5B030C2E11E\r
+S315000107E040239FE5B030C2E13C239FE5B030C2E132\r
+S315000107F038239FE5B030C2E134239FE5B030C2E132\r
+S3150001080030239FE5B030C2E12C239FE5B030C2E131\r
+S3150001081028239FE5B030C2E124239FE5B030C2E131\r
+S3150001082020239FE5B030C2E11C239FE5B030C2E131\r
+S3150001083018239FE5B030C2E114239FE5B030C2E131\r
+S3150001084010239FE5B030C2E10C239FE5B030C2E131\r
+S3150001085008239FE5B030C2E104239FE5B030C2E131\r
+S3150001086000239FE5B030C2E1FC229FE5B030C2E132\r
+S31500010870F8229FE5B030C2E1F4229FE5B030C2E133\r
+S31500010880F0229FE5B030C2E1EC229FE5B030C2E133\r
+S31500010890E8229FE5B030C2E1E4229FE5B030C2E133\r
+S315000108A0E0229FE5B030C2E1DC229FE5B030C2E133\r
+S315000108B0D8229FE5B030C2E1D4229FE5B030C2E133\r
+S315000108C0D0229FE5B030C2E1CC229FE5CC129FE554\r
+S315000108D0B030C2E1C8229FE5C8C29FE5B010C2E1AF\r
+S315000108E0C4229FE5C4E29FE5B0C0C2E1C0229FE5F4\r
+S315000108F0C0429FE5B0E0C2E1BC229FE5B040C2E143\r
+S31500010900B8229FE5B030C2E1B4229FE5B030C2E122\r
+S31500010910B0229FE5B030C2E1AC229FE5B030C2E122\r
+S31500010920A8229FE5B030C2E1A4229FE5B030C2E122\r
+S31500010930A0229FE5B030C2E19C229FE5B030C2E122\r
+S3150001094098229FE5B030C2E194229FE5B030C2E122\r
+S3150001095090229FE5B030C2E18C229FE5B030C2E122\r
+S3150001096088229FE5B030C2E184229FE5B030C2E122\r
+S3150001097080229FE5B030C2E17C229FE5B030C2E122\r
+S3150001098078229FE5B030C2E174229FE5B030C2E122\r
+S3150001099070229FE5B030C2E16C229FE5B030C2E122\r
+S315000109A068229FE50209E0E3B000C2E160229FE50B\r
+S315000109B0B000C2E15C229FE5003082E558229FE546\r
+S315000109C0003082E554229FE5B030C2E150229FE516\r
+S315000109D0B010C2E14C229FE5B0C0C2E148229FE5BA\r
+S315000109E0B0E0C2E144229FE544129FE5B040C2E176\r
+S315000109F040229FE5B010C2E13C129FE53C229FE5F3\r
+S31500010A00B010C2E138229FE538129FE538529FE5C2\r
+S31500010A10B010C2E134229FE5B050C2E130229FE519\r
+S31500010A20B000C2E12C229FE50A60A0E3B060C2E1FA\r
+S31500010A3024229FE5003082E520229FE50170A0E394\r
+S31500010A40007082E518229FE5B050C2E114229FE5AD\r
+S31500010A50B000C2E110229FE5B030C2E10C229FE551\r
+S31500010A60B030C2E108229FE5B060C2E104229FE5F1\r
+S31500010A70003082E500229FE5003082E5FC219FE5FA\r
+S31500010A80003082E5F8219FE5003082E5F4219FE5FB\r
+S31500010A90003082E5F0319FE5B070C3E1EC319FE5AE\r
+S31500010AA09420E0E3B020C3E1E4319FE56420A0E3B4\r
+S31500010AB0B020C3E1DC319FE51B20A0E3B020C3E1F8\r
+S31500010AC0D4319FE5022BA0E3B020C3E1CC319FE5F1\r
+S31500010AD0072BA0E3B020C3E1C4319FE52F20A0E39B\r
+S31500010AE0B020C3E1BC319FE5272CA0E3B020C3E1D0\r
+S31500010AF0B4319FE5312CA0E3B020C3E1AC319FE5D1\r
+S31500010B00962EA0E3B020C3E1A4319FE54B2DA0E3CF\r
+S31500010B10B020C3E1F080BDE800B20200F0B10200EE\r
+S31500010B20E47F0200EE7F0200F07F0200EA7F02000E\r
+S31500010B30EC7F0200F27F0200E87F0200F47F0200F0\r
+S31500010B40F67F0200F87F0200FA7F0200FC7F0200B6\r
+S31500010B50FE7F020000800200028002000480020083\r
+S31500010B6006800200088002000A8002000C80020052\r
+S31500010B700E80020010800200128002001480020022\r
+S31500010B8016800200188002003280020034800200C2\r
+S31500010B9036800200388002003A8002003C80020062\r
+S31500010BA0764900002A8002007C4900002C80020060\r
+S31500010BB0CF3E00002E800200752B0000308002001F\r
+S31500010BC03E80020040800200428002004480020012\r
+S31500010BD046800200488002004A8002004C800200E2\r
+S31500010BE04E800200508002005280020054800200B2\r
+S31500010BF056800200588002005A8002005C80020082\r
+S31500010C005E800200AC800200AE8002001E800200FF\r
+S31500010C101A8002001C800200688002006C800200BB\r
+S31500010C2060800200228002002480020026800200E9\r
+S31500010C30288002005CEDFFFF8280020042FAFFFF7E\r
+S31500010C4084800200888002001CFDFFFF0FCCFFFF9D\r
+S31500010C508A80020092800200AA800200C4800200FB\r
+S31500010C606480020086800200908002009480020067\r
+S31500010C7096800200A6800200B0800200B4800200C5\r
+S31500010C80B8800200BC800200C0800200C880020059\r
+S31500010C908C8002008E800200A080020098800200F3\r
+S31500010CA09A800200A28002009C8002009E800200BF\r
+S31500010CB0A4800200A880020014309FE504E02DE51F\r
+S31500010CC0030051E10100500304F09D1404E09DE48A\r
+S31500010CD0800500EA68BF000014309FE504E02DE5B9\r
+S31500010CE0030051E10100500304F09D1404E09DE46A\r
+S31500010CF0ED0200EA20CB000004E02DE508109FE597\r
+S31500010D000100A0E304E09DE4EAFFFFEA68BF0000FA\r
+S31500010D100DC0A0E1F0D82DE9205090E504B04CE2D9\r
+S31500010D20000055E30040A0E1F0A81B19303094E51E\r
+S31500010D30446080E2000053E30600A0E1847084E28F\r
+S31500010D400E00001A703094E5642084E2000053E33B\r
+S31500010D500700A0E10200001A0130A0E3203084E57B\r
+S31500010D60F0A81BE9385082E5345082E57B0D00EB93\r
+S31500010D707C0084E20710A0E1920D00EBF5FFFFEA8B\r
+S31500010D805C5084E5585084E5605084E5730D00EBB2\r
+S31500010D903C0084E20610A0E18A0D00EB303094E5B8\r
+S31500010DA0C32FA0E1223F83E04331A0E1383084E53F\r
+S31500010DB0E3FFFFEA0DC0A0E1F0DF2DE9146090E545\r
+S31500010DC004B04CE2248086E2440086E202A0A0E15F\r
+S31500010DD00150A0E1007096E5004092E5670D00EB39\r
+S31500010DE00C3098E50090A0E3090053E1389088E5BE\r
+S31500010DF01000001A090054E1014044E2090000DA3A\r
+S31500010E000010D5E50600A0E10FE0A0E100F097E5AE\r
+S31500010E10000050E3F9FFFF0A000054E3015085E2A8\r
+S31500010E20014044E2F5FFFFCA200088E2590D00EBBC\r
+S31500010E300900A0E1F0AF1BE9C40A00EB000054E38E\r
+S31500010E40150000DA043098E50C2098E501C083E22C\r
+S31500010E50101098E502005CE100C0A003020051E118\r
+S31500010E600600A0E11100000A043098E50110D5E45E\r
+S31500010E70002098E5014044E20310C2E7013083E215\r
+S31500010E80043088E504C088E5103098E5013083E236\r
+S31500010E90103088E5000054E3E9FFFFCA0600A0E12F\r
+S31500010EA00FE0A0E10CF097E5C10A00EBDDFFFFEAD8\r
+S31500010EB00130A0E3343088E50FE0A0E10CF097E5BE\r
+S31500010EC0343098E5180088E2000053E30A00001A5E\r
+S31500010ED0383098E5000053E3EDFFFF0A00309AE54C\r
+S31500010EE00020A0E3033064E00390E0E300308AE5EC\r
+S31500010EF0342088E5382088E5E7FFFFEA3C3098E5AD\r
+S31500010F00043083E03C3088E5360D00EB000050E309\r
+S31500010F100130A003383088053C3098E5033064E0A1\r
+S31500010F203C3088E5E9FFFFEA0DC0A0E1F0DF2DE9DD\r
+S31500010F30145090E504B04CE2644085E2840085E2F9\r
+S31500010F400280A0E10160A0E100A095E50B0D00EB98\r
+S31500010F500C3094E50070A0E3070053E10790A0E18F\r
+S31500010F60387084E51000001A003098E5017087E2B8\r
+S31500010F70030059E10300003A200084E2050D00EB6D\r
+S31500010F800900A0E1F0AF1BE90500A0E10FE0A0E137\r
+S31500010F9004F09AE50100C6E4002098E5020057E155\r
+S31500010FA0017087E2F7FFFF3AF2FFFFEA670A00EBFB\r
+S31500010FB0003098E5030057E11700002A103094E548\r
+S31500010FC00150A0E3000053E3180084E2140000DAA4\r
+S31500010FD0081094E5003094E5057087E00120D3E719\r
+S31500010FE00120C6E4083094E50C1094E5053083E051\r
+S31500010FF0083084E5082094E5010052E10030A003A1\r
+S3150001100008308405103094E5013043E2103084E560\r
+S31500011010003098E5030057E1E7FFFF3A640A00EB69\r
+S31500011020D4FFFFEA345084E5EE0C00EB000050E3F8\r
+S3150001103038508405383094E5000053E3F3FFFF0A86\r
+S315000110400030A0E30390E0E3007088E5343084E5E6\r
+S31500011050383084E5F0FFFFEA0100A0E30EF0A0E1DD\r
+S315000110600DC0A0E1F0DD2DE9011C41E2145090E52F\r
+S31500011070011041E204B04CE20370A0E102C0A0E11C\r
+S315000110800080A0E3244085E2646085E200A095E546\r
+S31500011090100051E301F19F97920000EAE010010070\r
+S315000110A018110100941101002C120100A81201006F\r
+S315000110B0E8120100E8120100E8120100E81201003D\r
+S315000110C0E8120100E8120100E8120100E81201002D\r
+S315000110D0E8120100E8120100E8120100F012010015\r
+S315000110E0003093E5130053E30800009A0CE085E213\r
+S315000110F00F00BEE80F00ACE800309EE51420A0E327\r
+S3150001110000308CE5002087E50800A0E1F0AD1BE981\r
+S315000111101500E0E3F0AD1BE90C3094E5000053E364\r
+S31500011120F8FFFF0A207084E20700A0E1930C00EBB0\r
+S31500011130060A00EB3C3094E5000053E31000000A78\r
+S31500011140185084E20160A0E3346084E50500A0E163\r
+S31500011150A40C00EB3C3094E5000050E30380E0036F\r
+S31500011160000053E3F7FFFF1A103094E5000053E344\r
+S31500011170F4FFFFCA0E0A00EB0700A0E1850C00EBA5\r
+S31500011180E0FFFFEA103094E5000053E3EBFFFFCAEE\r
+S31500011190F7FFFFEA0C3094E5000053E3D9FFFF0A9D\r
+S315000111A0206084E20600A0E1740C00EBE70900EB85\r
+S315000111B0103094E5000053E3080000DA0030A0E3A4\r
+S315000111C0103084E5102094E50500A0E1042084E5B3\r
+S315000111D0043094E5083084E50FE0A0E110F09AE5CB\r
+S315000111E00020A0E30230A0E10500A0E13C119FE54B\r
+S315000111F00FE0A0E108F09AE5343094E5000053E3EE\r
+S315000112000200001AEA0900EB0600A0E1DAFFFFEA94\r
+S315000112100130A0E3383084E5180084E2780C00EB55\r
+S315000112200030A0E3343084E5F5FFFFEA0C3096E5A3\r
+S31500011230000053E3B3FFFF0A204086E20400A0E169\r
+S315000112404E0C00EBC10900EB343096E5000053E388\r
+S315000112500D00001A0020A0E3102086E5103096E567\r
+S315000112600500A0E1043086E5041096E50230A0E110\r
+S31500011270081086E5411FA0E30FE0A0E108F09AE51A\r
+S31500011280CB0900EB0400A0E1BBFFFFEA0130A0E3BC\r
+S31500011290383086E5180086E2590C00EB0030A0E3F1\r
+S315000112A0343086E5EAFFFFEA0C3096E5000053E3A9\r
+S315000112B00700001A0C3094E5000053E391FFFF0A82\r
+S315000112C00130A0E3180084E2383084E54C0C00EBD1\r
+S315000112D08CFFFFEA0130A0E3180086E2383086E58C\r
+S315000112E0470C00EBF2FFFFEA1580E0E385FFFFEA1A\r
+S315000112F0003093E50F0053E384FFFF9A1030A0E31B\r
+S31500011300003087E50C3096E5000053E3003082E5B6\r
+S315000113101030961504308CE50C3094E5000053E34B\r
+S3150001132008308CE5103094150C308CE575FFFFEA1A\r
+S31500011330030100000DC0A0E110D82DE9144090E58D\r
+S3150001134004B04CE20400A0E100C094E50FE0A0E186\r
+S3150001135008F09CE510A81BE90DC0A0E170D82DE9A5\r
+S31500011360244080E2103094E504B04CE2000053E3DF\r
+S315000113700050A0E1006090E5150000DA002094E538\r
+S31500011380083094E50500A0E10310D2E70FE0A0E1E3\r
+S3150001139000F096E5000050E31800000A083094E5D5\r
+S315000113A00C1094E5013083E2083084E5082094E5C9\r
+S315000113B0010052E10030A00308308405103094E5A5\r
+S315000113C0013043E2103084E5102094E5000052E339\r
+S315000113D0E9FFFFCA0500A0E10FE0A0E110F096E5E4\r
+S315000113E0343094E5000053E370A81B090030A0E3F4\r
+S315000113F0180084E2343084E570681BE9000C00EAC9\r
+S315000114000C3094E5102094E5141094E5033062E065\r
+S31500011410010053E170A81BB9343094E5000053E391\r
+S31500011420340084151800841270A81B09F1FFFFEA25\r
+S3150001143010402DE964C080E210209CE50C309CE54B\r
+S315000114400040A0E1030052E118008CE2FF1001E226\r
+S315000114500C0000AA683094E5642094E50310C2E705\r
+S31500011460013083E2683084E504209CE50C309CE57C\r
+S31500011470030052E10030A00304308C0510309CE5D6\r
+S31500011480013083E210308CE534309CE5000053E3F3\r
+S315000114901080BD080030A0E334308CE51040BDE873\r
+S315000114A0D70B00EA142090E50530A0E30100A0E384\r
+S315000114B0090082E80EF0A0E1002090E5143092E5E3\r
+S315000114C00000A0E3081083E50EF0A0E10DC0A0E145\r
+S315000114D0F0DF2DE904B04CE24CD04DE20030A0E340\r
+S315000114E0006092E5140090E50350A0E1060053E187\r
+S315000114F06C300BE50390A0E1083090E502A0A0E175\r
+S3150001150070000BE50170A0E174300BE50880E0E3A3\r
+S31500011510015085E21400002A0130D7E474001BE56E\r
+S31500011520FF4003E20A0054E368104BE26C204BE2F1\r
+S315000115301900000A6C301BE528E04BE20EC083E07F\r
+S31500011540013083E23E0053E340404CE56C300BE54D\r
+S31500011550070000CA060055E10500000A0530A0E1B2\r
+S31500011560060053E1015085E2EAFFFF3A0800A0E1D7\r
+S31500011570F0AF1BE9AC0300EB000050E30080A0E1F3\r
+S3150001158000908A15F8FFFF1A6C301BE500609AE59A\r
+S31500011590039089E06C000BE5EFFFFFEA70C01BE5E5\r
+S315000115A000309CE5010013E3E1FFFF0A6C301BE507\r
+S315000115B028C04BE20CE083E0013083E20DC0A0E3DA\r
+S315000115C040C04EE56C300BE5D9FFFFEA0DC0A0E146\r
+S315000115D0F0DF2DE904B04CE208D04DE20040A0E373\r
+S315000115E0003092E5145090E5030054E10270A0E149\r
+S315000115F00190A0E1086095E51B00002A29804BE2D5\r
+S3150001160030A04BE20130A0E30600A0E10810A0E102\r
+S315000116100A20A0E130300BE5960300EB000050E311\r
+S315000116204100001A29305BE50430C9E7042095E53D\r
+S31500011630014084E2080012E30210A0E10700001A4B\r
+S31500011640FF3003E20A0053E32500000A1A0000CA2C\r
+S31500011650080053E30E00000A040012E30500001A15\r
+S31500011660003097E5030054E1E5FFFF3A0000A0E3EF\r
+S31500011670004087E5F0AF1BE90600A0E10810A0E1F4\r
+S315000116800A20A0E10130A0E330300BE5660300EB50\r
+S31500011690F2FFFFEA024054E20040A043EFFFFF4A97\r
+S315000116A0040012E30600A01184109F150A20A01160\r
+S315000116B00330A013F3FFFF1AE8FFFFEA0D0053E31F\r
+S315000116C00100000A7F0053E3E1FFFFEA020012E393\r
+S315000116D0E2FFFF1A010012E30A30A01329304B156D\r
+S315000116E004109515040011E30B00000A003095E57E\r
+S315000116F0010013E30230A0130130A0030600A0117C\r
+S315000117000A20A0112C109F150600A0010810A001A7\r
+S315000117100A20A00130300BE5430300EB29305BE5DD\r
+S31500011720042089E00000A0E3013042E5004087E59E\r
+S31500011730F0AF1BE93C1102004011020004E02DE567\r
+S31500011740143090E5080093E504E09DE4860300EA81\r
+S315000117500DC0A0E130D82DE914E090E54C009FE5DD\r
+S3150001176004B04CE2000051E103C0A0E10240A0E157\r
+S3150001177008009EE50050A0E30300000A880300EB81\r
+S315000117800050A0E10500A0E130A81BE9003093E577\r
+S315000117901500E0E3070053E330A81B990C009EE80F\r
+S315000117A00C0084E80830A0E300308CE5F4FFFFEA82\r
+S315000117B0010200000DC0A0E130D82DE914E090E54A\r
+S315000117C040009FE504B04CE2000051E10240A0E177\r
+S315000117D008009EE50050A0E30300000A850300EB24\r
+S315000117E00050A0E10500A0E130A81BE9003093E517\r
+S315000117F01500E0E3080053E330A81B190C0092E83A\r
+S315000118000C008EE8F6FFFFEA810200000EF0A0E16F\r
+S315000118100DC0A0E100D82DE904B04CE2140090E51A\r
+S31500011820F9FFFFEB0100A0E300A81BE90DC0A0E151\r
+S31500011830FF1001E200D82DE90100A0E104B04CE25D\r
+S315000118409B0100EB0100A0E300A81BE90DC0A0E18C\r
+S3150001185000D82DE904B04CE204D04DE20D004BE274\r
+S31500011860AB0100EB0D005BE500A81BE92C309FE501\r
+S315000118700120A0E10DC0A0E1030052E100D82DE94D\r
+S315000118801C009FE504B04CE218109FE51500E0131B\r
+S3150001189000A81B19FD0600EB0000A0E300A81BE948\r
+S315000118A081010000441102004811020004E02DE507\r
+S315000118B01C209FE51C009FE5003092E5013083E284\r
+S315000118C0010053E3003082E504F09D1404E09DE439\r
+S315000118D0150D00EAD4200200ECAE020004E02DE56D\r
+S315000118E008109FE50100A0E304E09DE4F9FCFFEA8E\r
+S315000118F020CB00000DC0A0E1F0D92DE904B04CE2E7\r
+S3150001190008D04DE20050A0E1FA8FA0E324704BE22B\r
+S3150001191028604BE27D0F55E380409FC5070000CA52\r
+S31500011920053185E0033183E0033263E00343A0E13F\r
+S315000119300400A0E1FA1FA0E3D02E00EB0040A0E1D5\r
+S315000119400700A0E1F02500EB0600A0E1EE2500EB83\r
+S3150001195028004BE2030090E8011040E0000051E34B\r
+S3150001196028100BE55D1C81B2C01081B228100BB5A1\r
+S31500011970040051E1F3FFFFBA980103E020209FE53F\r
+S31500011980C31FA0E19203C3E0C33471E005506310A5\r
+S3150001199001504502000055E3F0A91BD9DCFFFFEA1F\r
+S315000119A0E02E0000F11976050732A0E303F0A0E16D\r
+S315000119B00EF0A0E10EF0A0E10DC0A0E100D82DE9E6\r
+S315000119C01C309FE504B04CE2182093E5000092E537\r
+S315000119D0103092E50FE0A0E103F0A0E1FF0000E284\r
+S315000119E000A81BE9500000000DC0A0E1F0DF2DE9C1\r
+S315000119F09C319FE504B04CE208D04DE294219FE56D\r
+S31500011A00001093E5186092E5000051E3F0AF1B0961\r
+S31500011A1000200FE100400FE1C04084E304F029E11A\r
+S31500011A2030200BE54F90A0E3000096E52410A0E3DB\r
+S31500011A300C3096E50FE0A0E103F0A0E1000096E589\r
+S31500011A400910A0E10C3096E50FE0A0E103F0A0E15A\r
+S31500011A503C319FE50070A0E3002093E50980A0E1F9\r
+S31500011A60020057E1190000AA2CA19FE52C319FE540\r
+S31500011A70000096E50720D3E7017087E22232A0E154\r
+S31500011A800340DAE70F2002E20250DAE70410A0E190\r
+S31500011A900C3096E50FE0A0E103F0A0E1000096E529\r
+S31500011AA00510A0E10C3096E50FE0A0E103F0A0E1FE\r
+S31500011AB0DC309FE5044088E0002093E5FF8004E2E6\r
+S31500011AC0055088E0020057E1FF8005E2E6FFFFBA14\r
+S31500011AD0000096E52310A0E30C3096E50FE0A0E1A7\r
+S31500011AE003F0A0E1B0309FE5000096E52812D3E7A8\r
+S31500011AF00C3096E50FE0A0E103F0A0E198309FE5F8\r
+S31500011B000F2008E20210D3E7000096E50C3096E5B7\r
+S31500011B100FE0A0E103F0A0E1000096E5102096E5B4\r
+S31500011B200FE0A0E102F0A0E10030A0E1FF3003E206\r
+S31500011B302B0053E329004BE20110A0E329304BE5CA\r
+S31500011B400900000A750100EB000050E344309F15BF\r
+S31500011B500120A013442083150300001A29305BE5F8\r
+S31500011B602D0053E3AFFFFF0AEAFFFFEA20209FE5BE\r
+S31500011B700010A0E3001082E530201BE500300FE1E4\r
+S31500011B80C04002E2C030C3E3043083E103F029E13F\r
+S31500011B90F0AF1BE9D8200200500000005C110200E2\r
+S31500011BA0E4800200FF1001E20D0051E304E02DE59F\r
+S31500011BB02CC09FE504F09D0400209CE524309FE5A0\r
+S31500011BC00A0051E30310C2E7012082E200208CE5FE\r
+S31500011BD00100000A640052E304F09D1404E09DE450\r
+S31500011BE080FFFFEAD8200200E48002000DC0A0E1D8\r
+S31500011BF0000052E370D82DE904B04CE20060A0E188\r
+S31500011C000150A0E1014042E270A81B090110D5E490\r
+S31500011C100600A0E1FF1001E2E1FFFFEB000054E343\r
+S31500011C20014044E270A81B09F7FFFFEA0DC0A0E1DD\r
+S31500011C30000052E370D82DE904B04CE20060A0E147\r
+S31500011C400150A0E1014042E270A81B090600A0E193\r
+S31500011C5058FFFFEB000054E30100C5E4014044E2F4\r
+S31500011C6070A81B09F8FFFFEA0DC0A0E10E002DE9DF\r
+S31500011C7000D82DE910B04CE204309BE5080053E38F\r
+S31500011C800100000A0000A0E300A81BE955FFFFEBD5\r
+S31500011C90FBFFFFEA0DC0A0E130D82DE964409FE5C6\r
+S31500011CA004B04CE2343094E50000E0E30FE0A0E13B\r
+S31500011CB003F0A0E1343094E50050A0E10200E0E336\r
+S31500011CC00FE0A0E103F0A0E1141094E538309FE5A0\r
+S31500011CD038209FE5043081E534309FE5082081E511\r
+S31500011CE00C3081E52C209FE52C309FE5102081E505\r
+S31500011CF0143081E5342094E50500A0E10FE0A0E170\r
+S31500011D0002F0A0E130A81BE950000000EC1B010025\r
+S31500011D102C1C0100A41B0100B8190100681C01005C\r
+S31500011D200DC0A0E100D82DE91C309FE504B04CE2BE\r
+S31500011D30182093E5000092E5103092E50FE0A0E14E\r
+S31500011D4003F0A0E1FF0000E200A81BE9500000003B\r
+S31500011D500DC0A0E100D82DE91C309FE504B04CE28E\r
+S31500011D60182093E5FF1001E2000092E50C3092E5A0\r
+S31500011D700FE0A0E103F0A0E100A81BE9500000007C\r
+S31500011D800DC0A0E1000052E370D82DE904B04CE289\r
+S31500011D900060A0E10150A0E1014042E270A81B09E8\r
+S31500011DA00110D5E40600A0E1FF1001E2E7FFFFEB19\r
+S31500011DB0000054E3014044E270A81B09F7FFFFEA63\r
+S31500011DC00DC0A0E1000052E370D82DE904B04CE249\r
+S31500011DD00060A0E10150A0E1014042E270A81B09A8\r
+S31500011DE00600A0E1CDFFFFEB000054E30100C5E4CE\r
+S31500011DF0014044E270A81B09F8FFFFEA0E002DE935\r
+S31500011E000000A0E30CD08DE20EF0A0E10DC0A0E130\r
+S31500011E1030D82DE964409FE504B04CE2343094E5B6\r
+S31500011E200000E0E30FE0A0E103F0A0E1343094E527\r
+S31500011E300050A0E10200E0E30FE0A0E103F0A0E121\r
+S31500011E40141094E538309FE538209FE5043081E58C\r
+S31500011E5034309FE5082081E50C3081E52C209FE593\r
+S31500011E602C309FE5102081E5143081E5342094E57E\r
+S31500011E700500A0E10FE0A0E102F0A0E130A81BE916\r
+S31500011E8050000000801D0100C01D0100501D010011\r
+S31500011E90201D0100FC1D010010209FE50030D2E548\r
+S31500011EA0000053E30130A0030030C2050EF0A0E1AB\r
+S31500011EB0DC2002000DC0A0E100D82DE94C209FE5F1\r
+S31500011EC0FF0000E2143092E50010A0E1000053E3A8\r
+S31500011ED0183092050010A00104B04CE2000093E511\r
+S31500011EE00C3093E50FE0A0E103F0A0E11C209FE593\r
+S31500011EF00010A0E3443092E50100A0E1010053E1A6\r
+S31500011F0000A81B09441082E500681BE98E0000EA5F\r
+S31500011F10500000000DC0A0E110D82DE928209FE552\r
+S31500011F200040A0E1143092E504B04CE2000053E316\r
+S31500011F3018309205000093E5103093E50FE0A0E11B\r
+S31500011F4003F0A0E10000C4E510A81BE95000000061\r
+S31500011F500DC0A0E100D82DE944009FE504B04CE294\r
+S31500011F60182090E5003090E50338A0E12338A0E180\r
+S31500011F700C3043E2330053E300A81B894130A0E350\r
+S31500011F80000052E30510A0E3003080E500A81B091C\r
+S31500011F90000092E5143092E50FE0A0E103F0A0E124\r
+S31500011FA000A81BE9500000000DC0A0E110D82DE9E2\r
+S31500011FB05C309FE504B04CE204D04DE20040A0E362\r
+S31500011FC018C093E50020A0E104005CE10130A0E126\r
+S31500011FD014400BE514104BE20700000A00009CE5D3\r
+S31500011FE018C09CE50FE0A0E10CF0A0E114301BE560\r
+S31500011FF00040A0E1000053E30100001A0400A0E143\r
+S3150001200010A81BE90C309FE5000093E54E0000EB9C\r
+S31500012010F9FFFFEA5000000020B202000DC0A0E166\r
+S3150001202070D82DE99C209FE504B04CE204D04DE226\r
+S315000120300030A0E3185092E50040A0E1000055E30E\r
+S315000120401C300BE50160A0E1010040E20500000A39\r
+S31500012050003092E50610A0E30338A0E12338A0E1A1\r
+S31500012060410053E31200000A000054E10420A0E1FC\r
+S315000120700630A0E11C104BE20100000A0000A0E3BB\r
+S3150001208070A81BE9000095E518C095E50FE0A0E1F1\r
+S315000120900CF0A0E11C301BE5000053E3F6FFFF0A3C\r
+S315000120A024309FE5000093E5270000EB0100A0E343\r
+S315000120B070A81BE9000095E5143095E50FE0A0E155\r
+S315000120C003F0A0E1E7FFFFEA5000000020B20200A2\r
+S315000120D034109FE504E02DE530309FE530209FE583\r
+S315000120E0403081E52C309FE5482081E528209FE599\r
+S315000120F0203081E50100A0E10030A0E31C2081E54C\r
+S315000121004C3081E504E09DE4A11500EA5000000091\r
+S31500012110A8190100F4180100B0190100B419010051\r
+S31500012120000051E30600000A011041E20130D0E748\r
+S31500012130030053E30100A0030EF0A001000051E3E8\r
+S31500012140F8FFFF1A0000A0E30EF0A0E10DC0A0E128\r
+S3150001215000D82DE940309FE50120A0E3002083E56A\r
+S3150001216038309FE5000050E304B04CE230009F0593\r
+S315000121703C0090158C2093E50FE0A0E102F0A0E170\r
+S3150001218014309FE5002093E5000052E3012042E26E\r
+S31500012190002083E500A81BD9F8FFFFEA40B2020040\r
+S315000121A050000000802101000DC0A0E130D82DE9CA\r
+S315000121B080209FE504B04CE2003092E50040A0E1AA\r
+S315000121C00338A0E12338A0E1410053E30150A0E127\r
+S315000121D000C0E0E30D00000A0C0054E10510A0E187\r
+S315000121E00400A0E10500000A0400A0E10510A0E139\r
+S315000121F0692300EB0030A0E10300A0E130A81BE950\r
+S3150001220068FFFFEB003050E2FAFFFF1AF5FFFFEA25\r
+S31500012210183092E50610A0E3000053E3EDFFFF0A34\r
+S31500012220000093E5143093E50FE0A0E103F0A0E18F\r
+S3150001223000C0A0E1E7FFFFEA5000000004E02DE541\r
+S3150001224000C0D0E502E0A0E100005CE30C20A0E1C3\r
+S315000122500F00000A0030D1E5000053E30C00000A2C\r
+S31500012260FF2002E2FF3003E2030052E1011081E2A6\r
+S31500012270010080E21400001A00C0D0E500005CE312\r
+S315000122800C20A0E10200000A0030D1E5000053E372\r
+S31500012290F2FFFF1AFF001CE30400000A013051E5BA\r
+S315000122A02F0053E30130A00300008E050700000A4A\r
+S315000122B0FF001CE30400001A0030D1E5000053E3DF\r
+S315000122C000008E050130A0030000000A0030A0E3E3\r
+S315000122D00300A0E104F09DE40DC0A0E110D82DE9B2\r
+S315000122E060309FE504B04CE2002093E5000052E324\r
+S315000122F010A81B1950409FE550309FE5030054E19B\r
+S315000123000C00000A0400A0E10FE0A0E10CF094E546\r
+S31500012310000050E3183094151830940501308313EA\r
+S315000123200130C303183084E520309FE51C4084E268\r
+S31500012330030054E1F2FFFF1A08309FE50120A0E3F4\r
+S31500012340002083E510A81BE9E0200200D02102004D\r
+S31500012350082202000DC0A0E170D82DE9C0209FE53A\r
+S31500012360C0309FE504B04CE20CD04DE2030052E1CF\r
+S315000123700040A0E10160A0E124200BE50C00000A69\r
+S315000123801C504BE2001092E50400A0E10520A0E1FB\r
+S31500012390A9FFFFEB000050E30700001A24201BE50C\r
+S315000123A080309FE51C2082E2030052E124200BE5E8\r
+S315000123B0F3FFFF1A0100E0E370A81BE924201BE5E7\r
+S315000123C0040092E5000050E320000B050E00001A00\r
+S315000123D0103092E5000053E30200001A0000A0E36A\r
+S315000123E0002086E570A81BE920101BE51C201BE5D3\r
+S315000123F024004BE20FE0A0E103F0A0E1000050E36E\r
+S3150001240070A81B1924201BE5F3FFFFEA20104BE2FD\r
+S31500012410CFFFFFEB000050E370A81B1924201BE53A\r
+S31500012420EAFFFFEAD0210200082202000DC0A0E166\r
+S3150001243010D82DE9084090E504B04CE2003094E54F\r
+S31500012440C9E0E0E3000053E302C0A0E10700000A8F\r
+S31500012450000052E30200000A00309CE500E053E26E\r
+S315000124600200000A0FE0A0E100F094E500E0A0E11F\r
+S315000124700E00A0E110A81BE90DC0A0E110D82DE9BE\r
+S31500012480084090E504B04CE2043094E5C9E0E0E38D\r
+S31500012490000053E302C0A0E10700000A000052E376\r
+S315000124A00200000A00309CE500E053E20200000A47\r
+S315000124B00FE0A0E104F094E500E0A0E10E00A0E148\r
+S315000124C010A81BE90DC0A0E130D82DE9085090E510\r
+S315000124D000E0A0E1080095E504B04CE2000050E3FD\r
+S315000124E0C940E0E302C0A0E10800000A000052E38F\r
+S315000124F00E00A0E10200000A00C09CE500405CE27B\r
+S315000125000200000A0FE0A0E108F095E50040A0E115\r
+S315000125100400A0E130A81BE90DC0A0E130D82DE9E7\r
+S31500012520085090E500E0A0E10C0095E504B04CE20E\r
+S31500012530000050E3C940E0E302C0A0E10800000A40\r
+S31500012540000052E30E00A0E10200000A00C09CE573\r
+S3150001255000405CE20200000A0FE0A0E10CF095E504\r
+S315000125600040A0E10400A0E130A81BE90DC0A0E1F4\r
+S3150001257000D82DE904B04CE208C090E5C9E0E0E3DB\r
+S3150001258010309CE5000053E30100001A0E00A0E1A3\r
+S3150001259000A81BE90FE0A0E103F0A0E100E0A0E143\r
+S315000125A0F9FFFFEA0DC0A0E130D82DE9085090E50A\r
+S315000125B000E0A0E1140095E504B04CE2000050E310\r
+S315000125C0C940E0E303C0A0E10800000A000053E3AC\r
+S315000125D00E00A0E10200000A00C09CE500405CE29A\r
+S315000125E00200000A0FE0A0E114F095E50040A0E129\r
+S315000125F00400A0E130A81BE90DC0A0E130D82DE907\r
+S31500012600085090E500E0A0E1180095E504B04CE221\r
+S31500012610000050E3C940E0E303C0A0E10800000A5E\r
+S31500012620000053E30E00A0E10200000A00C09CE591\r
+S3150001263000405CE20200000A0FE0A0E118F095E517\r
+S315000126400040A0E10400A0E130A81BE9C900E0E3D5\r
+S315000126500EF0A0E1C900E0E30EF0A0E1C900E0E35D\r
+S315000126600EF0A0E1C900E0E30EF0A0E1C900E0E34D\r
+S315000126700EF0A0E1C900E0E30EF0A0E1C900E0E33D\r
+S315000126800EF0A0E10DC0A0E100D82DE904B04CE2A6\r
+S31500012690020000EB020000EB020000EBE40E00EB8F\r
+S315000126A00EF0A0E10EF0A0E10EF0A0E10DC0A0E158\r
+S315000126B010D82DE9FF4000E20A0054E304B04CE2D1\r
+S315000126C00D00A0E30200000A0400A0E110681BE966\r
+S315000126D0F7FDFFEAF6FDFFEBFAFFFFEA04E02DE561\r
+S315000126E0FF0000E204E09DE4EFFFFFEA0EF0A0E147\r
+S315000126F004309FE5000083E50EF0A0E1E42002002E\r
+S315000127000DC0A0E110D82DE90040A0E10000D0E500\r
+S3150001271004B04CE2000050E310A81B09FF0000E2E0\r
+S31500012720E1FFFFEB0100F4E5000050E310A81B09EF\r
+S31500012730F9FFFFEA0DC0A0E100D82DE9000050E342\r
+S3150001274004B04CE200C0A0E304D04DE22D20A0E38A\r
+S31500012750000060B22B20A0A30C30A0E10A10A0E378\r
+S3150001276000C08DE5560000EB00A81BE90DC0A0E1F5\r
+S3150001277000D82DE904B04CE200C0A0E304D04DE23C\r
+S315000127800C30A0E11010A0E32B20A0E300C08DE5E2\r
+S315000127904B0000EB00A81BE90DC0A0E1F0DF2DE91D\r
+S315000127A004B04CE224D04DE20160A0E10050A0E16A\r
+S315000127B004C09BE54C300BE500005CE32070A003F0\r
+S315000127C03070A01328304BE21F40A0E3014054E2D1\r
+S315000127D0207043E5013083E2FBFFFF5A063095E1A5\r
+S315000127E00040A0E33030A0030140840248304B058D\r
+S315000127F01700000A063095E11500000A0280A0E1E3\r
+S315000128000090A0E328A04BE20930A0E10820A0E156\r
+S315000128100610A0E10500A0E13E2D00EB9C209FE5FE\r
+S31500012820014084E200C0D2E70610A0E10500A0E164\r
+S315000128300930A0E10820A0E120C04AE5A02B00EB69\r
+S315000128400160A0E10050A0E1063090E101A08AE21A\r
+S31500012850ECFFFF1A08309BE54C201BE5030054E111\r
+S315000128600340A0B12D0052E3014044120900000AC1\r
+S31500012870000054E3F0AF1BB928204BE2023084E09C\r
+S31500012880200053E5014044E287FFFFEB000054E3DB\r
+S31500012890F0AF1BB9F7FFFFEA28304BE2042083E0D3\r
+S315000128A0213052E5070053E128304B020140440232\r
+S315000128B0042083004C301BE5203042E5EBFFFFEAA4\r
+S315000128C0701102000DC0A0E170D82DE904B04CE2F0\r
+S315000128D008D04DE201C0A0E10260A0E10040A0E104\r
+S315000128E00050A0E30C20A0E104C09BE503E0A0E1B9\r
+S315000128F00510A0E10400A0E10630A0E100E08DE5AD\r
+S3150001290004C08DE5A3FFFFEB70A81BE900C0A0E1A1\r
+S31500012910000050E304E02DE50100A0E30C00A00156\r
+S3150001292004F09D040030DCE50C10A0E1000053E347\r
+S3150001293004F09D0448E09FE5FF2003E201306CE0CE\r
+S315000129400E0053E10000A0A30D0052E30A0052134A\r
+S315000129500400000A080052E3203042E20100000AA6\r
+S315000129605E0053E30000A083000050E3011081E202\r
+S3150001297004F09D040030D1E5000053E304F09D040A\r
+S31500012980ECFFFFEA010800000DC0A0E1F0DF2DE930\r
+S315000129900150A0E10040A0E1051094E104B04CE231\r
+S315000129A050D04DE23030A00378604BE20270A0E1D6\r
+S315000129B000A0A0E377604B0278304B051500000AB2\r
+S315000129C0052094E11300000A0380A0E1C89FA0E15D\r
+S315000129D00930A0E10820A0E10510A0E10400A0E172\r
+S315000129E0CC2C00EB04309BE5000083E00030D0E501\r
+S315000129F00510A0E10400A0E10130C6E40930A0E120\r
+S31500012A000820A0E12E2B00EB0150A0E10040A0E13F\r
+S31500012A10051094E1EDFFFF1A78204BE2020056E122\r
+S31500012A200500000A013076E578104BE2010056E117\r
+S31500012A3001A08AE20130C7E4F9FFFF1A0030A0E3E2\r
+S31500012A400030C7E50A00A0E1F0AF1BE90DC0A0E127\r
+S31500012A50F0DF2DE904B04CE26CD04DE20260A0E15A\r
+S31500012A606C000BE50200A0E10190A0E170300BE5DE\r
+S31500012A70A5FFFFEB0080A0E3000050E30020A0E3E8\r
+S31500012A800010A0E368004BE280304BE278000BE5D2\r
+S31500012A90060003E90870A0E11102000A0020D6E54C\r
+S31500012AA00110D6E4000052E3FF5001E20C00000AD7\r
+S31500012AB0250055E30C00000A0500A0E10910A0E17C\r
+S31500012AC06C201BE50FE0A0E102F0A0E1018088E2A5\r
+S31500012AD00020D6E50110D6E4000052E3FF5001E2E2\r
+S31500012AE0F2FFFF1A0800A0E1F0AF1BE90130D6E4BE\r
+S31500012AF000C0A0E3FF5003E22D0055E380C00BE5C3\r
+S31500012B000130D6040140A003FF50030280400B05AB\r
+S31500012B10300055E30130D60401E0A003FF50030263\r
+S31500012B20303045E27CE00B057CC00B15090053E310\r
+S31500012B300C00A0E10CA0A0E10700008A0110D6E478\r
+S31500012B400A218AE0822085E0FF5001E2303045E229\r
+S31500012B50090053E330A042E2F7FFFF9A2E0055E346\r
+S31500012B60D101000A0020A0E36C0055E374200BE5B7\r
+S31500012B70C501000A7A0055E30130D604FF5003026D\r
+S31500012B80423045E2360053E303F19F97440000EAE1\r
+S31500012B906C2C0100A42C01006C2C0100A42C01005A\r
+S31500012BA0A42C0100A42C0100A42C0100A42C0100DA\r
+S31500012BB0A42C0100A42C0100A42C0100A42C0100CA\r
+S31500012BC0A42C0100A42C0100A42C0100A42C0100BA\r
+S31500012BD0A42C0100A42C0100A42C01006C2C0100E2\r
+S31500012BE0A42C0100A42C01006C2C0100A42C0100D2\r
+S31500012BF0A42C0100A42C0100A42C0100A42C01008A\r
+S31500012C00A42C0100A42C0100A42C0100A42C010079\r
+S31500012C106C2C0100A42C01006C2C0100A42C0100D9\r
+S31500012C20A42C0100A42C0100A42C0100A42C010059\r
+S31500012C30A42C0100A42C0100A42C0100A42C010049\r
+S31500012C40A42C0100A42C01006C2C0100A42C010071\r
+S31500012C50A42C0100A42C0100A42C01006C2C010061\r
+S31500012C60A42C0100A42C01006C2C0100000050E3EF\r
+S31500012C707C01000A70301BE580404BE2060093E8B8\r
+S31500012C8008E083E2060004E970E00BE5440055E341\r
+S31500012C90640055136B01001A84101BE5000051E313\r
+S31500012CA0600100BA253045E2530053E303F19F97D3\r
+S31500012CB04F0100EAB4300100F4310100F4310100A2\r
+S31500012CC0F4310100F4310100F4310100F431010065\r
+S31500012CD0F4310100F4310100F4310100F431010055\r
+S31500012CE0F4310100F4310100F4310100F431010045\r
+S31500012CF0F4310100F4310100F4310100F431010035\r
+S31500012D00F4310100F4310100F4310100F431010024\r
+S31500012D10F4310100F4310100F4310100F431010014\r
+S31500012D20F4310100F4310100D430010040310100D9\r
+S31500012D30382E0100F4310100F4310100F4310100B3\r
+S31500012D40F4310100F4310100F4310100F4310100E4\r
+S31500012D50F4310100F4310100F4310100F4310100D4\r
+S31500012D60F4310100F4310100F43101006C3101004C\r
+S31500012D70F4310100382E0100F4310100F431010073\r
+S31500012D80382E0100F4310100F4310100F431010063\r
+S31500012D90F4310100F4310100F4310100F431010094\r
+S31500012DA0F4310100F4310100D43001004031010059\r
+S31500012DB0382E0100F4310100F4310100F431010033\r
+S31500012DC0F4310100F4310100F4310100F431010064\r
+S31500012DD0F4310100F4310100F4310100F431010054\r
+S31500012DE0042E0100F4310100F43101006C310100BF\r
+S31500012DF0F4310100382E0100F4310100F4310100F3\r
+S31500012E00382E01003000A0E30910A0E16C201BE57B\r
+S31500012E100FE0A0E102F0A0E10140A0E37800A0E309\r
+S31500012E200910A0E16C301BE50FE0A0E103F0A0E181\r
+S31500012E3008A0A0E37C400BE5443045E2340053E3AF\r
+S31500012E4003F19F973C0000EA1C2F01003C2F010073\r
+S31500012E503C2F01003C2F01003C2F01003C2F0100BB\r
+S31500012E603C2F01003C2F01003C2F01003C2F0100AB\r
+S31500012E703C2F01003C2F01003C2F01003C2F01009B\r
+S31500012E803C2F01003C2F01003C2F01001C2F0100AB\r
+S31500012E903C2F01003C2F0100843001003C2F010032\r
+S31500012EA03C2F01003C2F01003C2F01003C2F01006B\r
+S31500012EB03C2F01003C2F01003C2F01003C2F01005B\r
+S31500012EC03C2F01003C2F01001C2F01003C2F01006B\r
+S31500012ED03C2F01003C2F01003C2F01003C2F01003B\r
+S31500012EE03C2F01003C2F01003C2F01003C2F01002B\r
+S31500012EF03C2F01003C2F01009C3001003C2F0100BA\r
+S31500012F003C2F01003C2F01003C2F01001C2F01002A\r
+S31500012F103C2F01003C2F01009C30010080C04BE298\r
+S31500012F2003001CE924C49FE568204BE20A30A0E3B4\r
+S31500012F3000C08DE593FEFFEB0070A0E168304BE227\r
+S31500012F40014047E278300BE590400BE574001BE544\r
+S31500012F507C101BE5000050E30A4067E00140441283\r
+S31500012F60000051E32050A0030300000A74201BE572\r
+S31500012F703050A0E3000052E33800001A80E01BE560\r
+S31500012F8000005EE30B00001A000054E3014044E236\r
+S31500012F90080000DA0500A0E10910A0E16C201BE59C\r
+S31500012FA00FE0A0E102F0A0E1000054E3018088E215\r
+S31500012FB0014044E2F6FFFFCA74301BE5000053E30B\r
+S31500012FC01F00001A000057E390701BE50C0000DAA1\r
+S31500012FD078E01BE50910A0E10130DEE46C201BE579\r
+S31500012FE0FF5003E278E00BE50500A0E10FE0A0E168\r
+S31500012FF002F0A0E1000057E3018088E2017047E298\r
+S31500013000F2FFFFCA80301BE5000053E3AFFEFF0A63\r
+S31500013010000054E3014044E2ACFEFFDA2000A0E3E5\r
+S315000130200910A0E16CC01BE50FE0A0E10CF0A0E1E6\r
+S31500013030000054E3018088E2014044E2F6FFFFCA42\r
+S31500013040A2FEFFEA0300A0E10910A0E16CC01BE5A6\r
+S315000130500FE0A0E10CF0A0E1018088E2D8FFFFEAD1\r
+S315000130600200A0E10910A0E16C301BE50FE0A0E130\r
+S3150001307003F0A0E1018088E200C0A0E374C00BE583\r
+S31500013080BDFFFFEA80204BE2C4C29FE5030012E9BF\r
+S315000130901030A0E368204BE2A4FFFFEA80E04BE298\r
+S315000130A003001EE9ACC29FE568204BE21030A0E3A5\r
+S315000130B09EFFFFEA2500A0E30910A0E16C201BE5B5\r
+S315000130C00FE0A0E102F0A0E1013047E290300BE50C\r
+S315000130D09DFFFFEA00705AE20200001A000050E369\r
+S315000130E02070A0034070A01301E047E20040A0E376\r
+S315000130F00E0054E190E00BE58CE00BE50C0000AA14\r
+S3150001310068504BE280304BE2030013E90420A0E152\r
+S315000131103C2900EB010010E33130A0E32E30A0037F\r
+S315000131200130C5E48CC01BE5014084E20C0054E18A\r
+S31500013130F3FFFFBA68E04BE278E00BE582FFFFEAB6\r
+S3150001314070301BE50910A0E10050D3E56C401BE58A\r
+S315000131500500A0E10FE0A0E104F0A0E170C01BE5CD\r
+S3150001316004C08CE270C00BE557FEFFEA70301BE528\r
+S3150001317070C01BE5003093E504C08CE2000053E308\r
+S31500013180D4E19F0578300BE570C00BE578E00B05BF\r
+S315000131900300000A78001BE5DBFDFFEB000050E3AE\r
+S315000131A00C00000A78101BE50070A0E30730D1E798\r
+S315000131B0070053E100E0E00390E00B0562FFFF0A20\r
+S315000131C078201BE5017087E20730D2E7000053E360\r
+S315000131D0FAFFFF1ABBFFFFEA80019FE547FDFFEB00\r
+S315000131E078001BE560FDFFEB74019FE578000BE5B8\r
+S315000131F0EBFFFFEA2500A0E30910A0E16C401BE507\r
+S315000132000FE0A0E104F0A0E10500A0E10910A0E1B2\r
+S315000132100FE0A0E104F0A0E1028088E201C047E2EC\r
+S3150001322090C00BE548FFFFEA80404BE20C0014E931\r
+S315000132302DC0A0E3002072E20030E3E20C0004E9B5\r
+S3150001324074C00BE596FEFFEA80C04BE206001CE95E\r
+S31500013250F0308FE2180093E8031001E0042002E049\r
+S3150001326006000CE98EFEFFEA70301BE580E04BE2BA\r
+S31500013270002093E5041083E20230A0E1C34FA0E1F0\r
+S3150001328018000EE970100BE57FFEFFEA0130D6E467\r
+S3150001329001C0A0E3FF5003E26C0055E30130D60400\r
+S315000132A00C00A001FF50030231FEFFEA0120D6E423\r
+S315000132B07C101BE5FF5002E2303045E2011081E24D\r
+S315000132C0090053E37C100BE525FEFF8A0130D6E4A5\r
+S315000132D0FF5003E2302045E2090052E3FAFFFF9A6C\r
+S315000132E01FFEFFEA7C009FE504FDFFEB0600A0E15F\r
+S315000132F01DFDFFEB70009FE50740A0E3FFFCFFEB20\r
+S315000133002000A0E3E8FCFFEB70301BE5002093E50D\r
+S3150001331004C083E20200A0E10010A0E380304BE28A\r
+S31500013320030003E988001BE570C00BE50EFDFFEB0A\r
+S31500013330014054E2F1FFFF5A30009FE5EFFCFFEB3D\r
+S315000133400000A0E3F0AF1BE9FFFFFFFF0000000054\r
+S31500013350841102007011020090110200A4110200F2\r
+S31500013360AC110200C0110200C4110200DC110200FE\r
+S31500013370E01102000C0091E9020053E101C0A0E155\r
+S31500013380FF0000E20EF0A0A1003091E50100C3E4C8\r
+S31500013390003081E50010A0E30010C3E508209CE59C\r
+S315000133A0012082E208208CE50EF0A0E10DC0A0E12B\r
+S315000133B00E002DE900D82DE910B04CE20CD04DE2FB\r
+S315000133C000C0A0E101EBA0E318C00BE518104BE229\r
+S315000133D000C0A0E304209BE508308BE210009FE5C6\r
+S315000133E014E00BE510C00BE597FDFFEB10001BE5A4\r
+S315000133F000A81BE9743301000DC0A0E10C002DE902\r
+S3150001340010D82DE90CB04CE20CD04DE200C0A0E181\r
+S315000134100140A0E100E0A0E31C104BE204209BE583\r
+S3150001342008308BE214009FE51CC00BE514E00BE5A8\r
+S3150001343018400BE584FDFFEB14001BE510A81BE902\r
+S31500013440743301000DC0A0E110D82DE904B04CE29F\r
+S3150001345001C0A0E100E0A0E10CD04DE20230A0E104\r
+S315000134601C104BE20C20A0E10040A0E301CBA0E33D\r
+S3150001347014009FE51CE00BE518C00BE514400BE5B5\r
+S3150001348071FDFFEB14001BE510A81BE97433010065\r
+S315000134900DC0A0E10F002DE900D82DE918309FE5F8\r
+S315000134A014B04CE2000093E504209BE508308BE262\r
+S315000134B00010A0E364FDFFEB00A81BE9E420020075\r
+S315000134C004E02DE514309FE50020A0E1000093E51E\r
+S315000134D00130A0E10010A0E304E09DE45AFDFFEAFB\r
+S315000134E0E42002000DC0A0E1010052E1F0D92DE96E\r
+S315000134F00260A0E102606180000056E304B04CE284\r
+S315000135000170A0E10050A0E10380A0E1F0A91BD960\r
+S31500013510000058E307106810C0009F15BC009F0506\r
+S315000135200710A0010FE0A0E105F0A0E10040A0E333\r
+S31500013530060054E1A8009FE5240000AA0410D7E77D\r
+S315000135400FE0A0E105F0A0E1070054E394009FE538\r
+S315000135501B00000A014084E20F0054E3F3FFFFDA87\r
+S3150001356084009FE50FE0A0E105F0A0E10040A0E3A3\r
+S31500013570060054E12010A0A3030000AA0410D7E717\r
+S31500013580203041E25E0053E32E10A0835C009FE5EC\r
+S31500013590014084E20FE0A0E105F0A0E10F0054E351\r
+S315000135A0F2FFFFDA48009FE5106046E20FE0A0E176\r
+S315000135B005F0A0E1000056E3107087E2F0A91BD9DF\r
+S315000135C0D2FFFFEA0FE0A0E105F0A0E1E0FFFFEA8C\r
+S315000135D020009FE50FE0A0E105F0A0E1D9FFFFEA99\r
+S315000135E0E4110200EC11020010120200F4110200B3\r
+S315000135F0F8110200FC1102006809020010402DE9D1\r
+S3150001360000C0A0E10140A0E110009FE50230A0E169\r
+S315000136100C10A0E10420A0E11040BDE8B0FFFFEAD4\r
+S315000136209034010004E02DE50020A0E304E09DE4D0\r
+S31500013630F1FFFFEA0DC0A0E1000051E1F0D92DE94B\r
+S315000136400150A0E101506080000055E304B04CE256\r
+S315000136500060A0E10280A0E1F0A91BD9000058E3B7\r
+S31500013660061068105C009F1558009F050610A00102\r
+S3150001367086FFFFEBC53FA0E1237F85E00040A0E385\r
+S31500013680470154E140009FE50B0000AA041196E7AB\r
+S315000136907EFFFFEB014084E2030054E3F7FFFFDA0C\r
+S315000136A028009FE5105045E278FFFFEB000055E347\r
+S315000136B0106086E2F0A91BD9E7FFFFEA10009FE53B\r
+S315000136C072FFFFEBF2FFFFEAE411020000120200B3\r
+S315000136D0180F02000812020004E02DE50020A0E305\r
+S315000136E004E09DE4D2FFFFEA0DC0A0E1000051E134\r
+S315000136F0F0D92DE90150A0E101506080000055E3A9\r
+S3150001370004B04CE20060A0E10280A0E1F0A91BD95F\r
+S31500013710000058E3061068106C009F1568009F05AD\r
+S315000137200610A00159FFFFEB0040A0E3C57FA0E111\r
+S31500013730A73F85E0C30054E150009FE58420A0E146\r
+S315000137404C009FA50E0000AAB61092E14FFFFFEBB9\r
+S31500013750030054E33C009FE50900000A014084E2AE\r
+S31500013760070054E3F1FFFFDA2C009FE5105045E214\r
+S3150001377046FFFFEB000055E3106086E2F0A91BD976\r
+S31500013780E2FFFFEA41FFFFEBF3FFFFEAE41102006C\r
+S31500013790141202000C12020010120200180F02008D\r
+S315000137A004E02DE50020A0E304E09DE4CDFFFFEA5F\r
+S315000137B014309FE504E02DE5030051E101005003BB\r
+S315000137C004F09D1404E09DE4B2F9FFEA74270000B9\r
+S315000137D004E02DE508109FE50100A0E304E09DE467\r
+S315000137E0F2FFFFEA74270000030052E302C0A0E1E2\r
+S315000137F004E02DE50020A0E10200009A003081E1FD\r
+S31500013800030013E30800000A01C04CE201007CE357\r
+S3150001381004F09D040130D1E401C04CE201007CE3D7\r
+S315000138200130C2E404F09D04F9FFFFEA0F005CE3F6\r
+S3150001383000E0A0E10A00009A043091E410C04CE2D5\r
+S3150001384004308EE4042091E40F005CE304208EE44E\r
+S31500013850043091E404308EE4042091E404208EE4E3\r
+S31500013860F4FFFF8A03005CE30400009A043091E44C\r
+S3150001387004C04CE203005CE304308EE4FAFFFF8AE5\r
+S3150001388001C04CE201007CE30E20A0E104F09D049E\r
+S315000138900130D1E401C04CE201007CE30130C2E415\r
+S315000138A004F09D04F9FFFFEA030052E30030A0E1B2\r
+S315000138B00100009A030010E30700000A012042E21A\r
+S315000138C0010072E30EF0A001012042E2010072E361\r
+S315000138D00110C3E40EF0A001FAFFFFEAFF1001E2B6\r
+S315000138E001C481E10F0052E30030A0E10CC88CE174\r
+S315000138F00600009A04C083E404C083E4102042E277\r
+S3150001390004C083E40F0052E304C083E4F8FFFF8A96\r
+S31500013910030052E30300009A042042E2030052E34B\r
+S3150001392004C083E4FBFFFF8A000052E30EF0A0010E\r
+S31500013930012052E20110C3E40EF0A001FBFFFFEAF1\r
+S315000139400DC0A0E100D82DE904B04CE2380A00EB25\r
+S315000139500C209FE5003092E5013083E2003082E5DC\r
+S315000139600EF0A0E1F42002000DC0A0E100D82DE97F\r
+S3150001397004B04CE234209FE5003092E5013083E249\r
+S31500013980003082E5003092E5010053E300A81B995F\r
+S31500013990003092E5013053E20300A0E100308215C8\r
+S315000139A00000000A00A81BE9E40900EBFCFFFFEA9E\r
+S315000139B0F42002000DC0A0E100D82DE92C209FE5DE\r
+S315000139C004B04CE2003092E5000053E300A81B0965\r
+S315000139D0003092E5013053E20300A0E10030821588\r
+S315000139E00000000A00A81BE9D40900EBFCFFFFEA6E\r
+S315000139F0F420020004309FE5000093E50EF0A0E1FB\r
+S31500013A00F42002000DC0A0E130D82DE904B04CE24B\r
+S31500013A100CD04DE201C0A0E110509BE50340A0E1AE\r
+S31500013A2002E0A0E100408DE50C20A0E108409BE505\r
+S31500013A3004C09BE50010A0E10E30A0E10500A0E165\r
+S31500013A4004C08DE508408DE5F60200EB0C309BE5E0\r
+S31500013A50005083E530A81BE904E02DE504E09DE470\r
+S31500013A60170500EA0DC0A0E110D82DE9383090E520\r
+S31500013A7004B04CE2100053E30040A0E10400000A48\r
+S31500013A80280500EB383094E50000A0E3100053E36D\r
+S31500013A9010A81B190400A0E16E0300EB0100A0E3CE\r
+S31500013AA010A81BE904E02DE504E09DE47F0400EA8B\r
+S31500013AB00DC0A0E110D82DE9383090E504B04CE2F4\r
+S31500013AC0100053E30040A0E10200000A0400A0E157\r
+S31500013AD010681BE9940400EA0F0300EBFAFFFFEA02\r
+S31500013AE004E02DE504E09DE40E0500EA04E02DE581\r
+S31500013AF004E09DE4D10400EA04E02DE50C309FE5E5\r
+S31500013B00000093E51C0080E204E09DE4DA0800EA87\r
+S31500013B100C8A020004309FE5000093E50EF0A0E157\r
+S31500013B200C8A020000009FE50EF0A0E15089020018\r
+S31500013B3004E02DE504E09DE4360500EA343090E525\r
+S31500013B40000053E330009015240090050EF0A0E12B\r
+S31500013B50240090E50EF0A0E10EF0A0E104E02DE5D1\r
+S31500013B6010309FE50120A0E10010A0E1000093E5DF\r
+S31500013B7004E09DE4760500EA0C8A0200000090E567\r
+S31500013B800EF0A0E1040090E50EF0A0E10DC0A0E169\r
+S31500013B9010D82DE904B04CE20140A0E3A8209FE52E\r
+S31500013BA0003092E5043083E0003082E500C090E504\r
+S31500013BB000005CE31B00000AB824DCE1B030D1E16F\r
+S31500013BC0030052E10C00000A0030A0E3003080E55A\r
+S31500013BD0B030C1E10340A0E16C209FE5003092E5E1\r
+S31500013BE0010053E2000082150100000A0400A0E171\r
+S31500013BF010A81BE9510900EBFBFFFFEA4C309FE5DA\r
+S31500013C00002093E502005CE19C309C150030A00386\r
+S31500013C10000053E300308015B834D311B030C11120\r
+S31500013C20ECFFFF1AE7FFFFEA20309FE5003093E53E\r
+S31500013C30000053E39C3093150C30A001003080E561\r
+S31500013C40B8C4D3E1B0C0C1E1E2FFFFEAF42002004B\r
+S31500013C50E82002000DC0A0E10008A0E110D82DE97E\r
+S31500013C604008A0E104B04CE274209FE5003092E5E3\r
+S31500013C70013083E2003082E568309FE5003093E54C\r
+S31500013C80000053E39C309315004053E20B00000AF9\r
+S31500013C900038A0E14C109FE52308A0E1B834D4E137\r
+S31500013CA00020A0E3000053E10400000A003091E582\r
+S31500013CB0030054E19C209415004052E2F6FFFF1ADE\r
+S31500013CC01C209FE5003092E5010053E200008215B9\r
+S31500013CD00100000A0400A0E110A81BE9170900EB86\r
+S31500013CE0FBFFFFEAF4200200E82002000DC0A0E17C\r
+S31500013CF00118A0E110D82DE94118A0E104B04CE269\r
+S31500013D000140A0E302C0A0E198209FE5003092E5C2\r
+S31500013D10043083E0003082E5B824D0E10138A0E127\r
+S31500013D20230852E10900000A0040A0E374209FE540\r
+S31500013D30003092E5010053E2000082150100000AFD\r
+S31500013D400400A0E110A81BE9FC0800EBFBFFFFEA59\r
+S31500013D5000005CE3F3FFFF0AB410CCE100008CE540\r
+S31500013D60383090E508308CE5982090E50C208CE5FC\r
+S31500013D70343090E5000053E330309015243090053F\r
+S31500013D8010308CE5243090E514308CE5002090E568\r
+S31500013D900030A0E318208CE5041090E520308CE576\r
+S31500013DA01C108CE5E0FFFFEAF420020004E02DE59B\r
+S31500013DB004E09DE4220500EA04E02DE504E09DE42B\r
+S31500013DC03E0500EA0C209FE5003092E5003183E0D4\r
+S31500013DD0800093E50EF0A0E10C8A020010209FE519\r
+S31500013DE0003092E5003183E0803083E20300A0E1F8\r
+S31500013DF00EF0A0E10C8A02000C209FE5003092E54E\r
+S31500013E00003183E0801083E50EF0A0E10C8A020008\r
+S31500013E100DC0A0E130D82DE904B04CE200C0A0E10C\r
+S31500013E2001E0A0E10C10A0E128C09FE508D04DE219\r
+S31500013E300240A0E10E20A0E100E09CE504C09BE564\r
+S31500013E400350A0E110009FE50430A0E120108DE8A9\r
+S31500013E50D30500EB30A81BE90C8A0200F0890200A9\r
+S31500013E6004E02DE510309FE50010A0E1002093E568\r
+S31500013E7008009FE504E09DE4D60500EA0C8A0200ED\r
+S31500013E80F089020004E02DE504E09DE4E10400EA86\r
+S31500013E900DC0A0E130D82DE904B04CE208D04DE2C6\r
+S31500013EA001C0A0E10C509BE502E0A0E10C20A0E1DD\r
+S31500013EB004C09BE50340A0E10010A0E10E30A0E1A3\r
+S31500013EC00500A0E110108DE8F30500EB08309BE535\r
+S31500013ED0005083E530A81BE904E02DE504E09DE4EC\r
+S31500013EE0FA0500EA04E02DE504E09DE45A0600EA3D\r
+S31500013EF004E02DE504E09DE4720600EA04E02DE508\r
+S31500013F0004E09DE4840600EA04E02DE50020A0E338\r
+S31500013F1004E09DE4850600EA04E02DE504E09DE465\r
+S31500013F20940600EA04E02DE504E09DE4A80600EA13\r
+S31500013F3004E02DE504E09DE4BC0600EA04E02DE57D\r
+S31500013F4004E09DE4C70600EA04E02DE504E09DE4F3\r
+S31500013F50C70600EA04E02DE504E09DE4D20600EA86\r
+S31500013F6004E02DE504E09DE4D20600EA04E02DE537\r
+S31500013F7004E09DE4D20600EA0EF0A0E10000A0E311\r
+S31500013F800EF0A0E10DC0A0E130D82DE90140A0E17D\r
+S31500013F900050A0E104B04CE20110A0E30400A0E14E\r
+S31500013FA0B91C00EB004085E530A81BE904E02DE5CE\r
+S31500013FB004E09DE4D31C00EA030090E90EF0A0E1C1\r
+S31500013FC0060080E90EF0A0E104E02DE50110A0E372\r
+S31500013FD004E09DE4E11C00EA04E02DE504E09DE433\r
+S31500013FE0DE1C00EA0DC0A0E130D82DE904B04CE298\r
+S31500013FF00340A0E108D04DE220304BE20250A0E19F\r
+S315000140001C000BE518100BE5060093E90400A0E17E\r
+S315000140108F1D00EB004085E530A81BE904E02DE586\r
+S3150001402004E09DE4981D00EA000081E50EF0A0E1A0\r
+S3150001403004402DE508D04DE206008DE818009DE804\r
+S31500014040100080E2180080E808D08DE21000BDE87B\r
+S315000140500EF0A0E104402DE5101081E2180091E870\r
+S3150001406008D04DE218008DE804309DE5043080E566\r
+S3150001407000209DE5002080E508D08DE21000BDE816\r
+S315000140800EF0A0E104309FE5000093E50EF0A0E1FB\r
+S315000140906421020008309FE5002093E5030092E9C0\r
+S315000140A00EF0A0E1642102000DC0A0E130D82DE997\r
+S315000140B004B04CE204509BE501C0A0E102E0A0E19E\r
+S315000140C00340A0E10010A0E10C20A0E10E30A0E128\r
+S315000140D00500A0E1B51F00EB005084E530A81BE9FF\r
+S315000140E004E02DE504E09DE4D41F00EA04D04DE28E\r
+S315000140F030402DE904D04DE210308DE510308DE2CF\r
+S31500014100300093E80430A0E114508DE504D08DE22F\r
+S315000141103040BDE804D08DE2D71F00EA04E02DE56A\r
+S3150001412004E09DE4512000EA04E02DE504E09DE46D\r
+S315000141301C2000EA04E02DE504E09DE4342000EAB9\r
+S315000141400DC0A0E130D82DE90050A0E104B04CE249\r
+S315000141500100A0E10140A0E1370B00EB004085E53D\r
+S3150001416030A81BE904E02DE504E09DE4380B00EAE4\r
+S3150001417004E02DE504E09DE4380B00EA04E02DE5BA\r
+S3150001418004E09DE43E0B00EA04E02DE504E09DE435\r
+S31500014190460B00EA04E02DE504E09DE4550B00EA38\r
+S315000141A004E02DE504E09DE4490B00EA04E02DE579\r
+S315000141B004E09DE4490B00EA04E02DE504E09DE4FA\r
+S315000141C0490B00EA040090E50EF0A0E1080090E535\r
+S315000141D0000050E20100A0130EF0A0E10C0090E5F2\r
+S315000141E0000050E20100A0130EF0A0E10DC0A0E115\r
+S315000141F000D82DE904B04CE29E0800EB00A81BE9AB\r
+S3150001420004E02DE504E09DE4A10800EA04E02DE5C3\r
+S3150001421004E09DE4A20800EA04E02DE504E09DE443\r
+S31500014220DA0800EA04E02DE504E09DE42E0900EA3F\r
+S3150001423004E02DE504E09DE4430900EA0DC0A0E198\r
+S3150001424010D82DE904B04CE20140A0E15E0900EB73\r
+S31500014250000084E510A81BE90DC0A0E100D82DE9F6\r
+S315000142600010A0E304B04CE25C0900EB00A81BE9D6\r
+S3150001427004E02DE504E09DE4800900EA04E02DE573\r
+S3150001428004E09DE4B50900EA04E02DE504E09DE4BF\r
+S315000142909F0900EA000051E30230A0E104E02DE5A8\r
+S315000142A0FF2002E20100000AFC0013E30100000AFC\r
+S315000142B00000A0E304F09DE404E09DE4F50900EAB2\r
+S315000142C004D04DE230402DE904D04DE210308DE5A9\r
+S315000142D0000051E310308DE202C0A0E1300093E806\r
+S315000142E0FF2002E20200000AFC001CE30430A0E108\r
+S315000142F00400000A0000A0E304D08DE23040BDE8CE\r
+S3150001430004D08DE20EF0A0E114508DE504D08DE2CB\r
+S315000143103040BDE804D08DE2320A00EA000051E3E4\r
+S315000143200230A0E104E02DE5FF2002E20100000ACF\r
+S31500014330FC0013E30100000A0000A0E304F09DE481\r
+S3150001434004E09DE4930A00EA000090E50EF0A0E186\r
+S31500014350040090E5000050E20100A0130EF0A0E178\r
+S315000143600DC0A0E100D82DE904B04CE2F10A00EB42\r
+S3150001437000A81BE904E02DE504E09DE4060B00EA34\r
+S3150001438004E02DE504E09DE4070B00EA04E02DE5D9\r
+S3150001439004E09DE4680B00EA04E02DE504E09DE4F9\r
+S315000143A0900B00EA04E02DE504E09DE4CF0B00EA62\r
+S315000143B004E02DE504E09DE4E80B00EA04E02DE5C8\r
+S315000143C004E09DE4F60B00EA0DC0A0E100D82DE95A\r
+S315000143D004B04CE2060C00EB00A81BE904E02DE555\r
+S315000143E004E09DE4110C00EA04E02DE5001090E5DF\r
+S315000143F004E09DE4110C00EA04E02DE504E09DE4EF\r
+S315000144003B0C00EA04E02DE504E09DE4550C00EACE\r
+S3150001441004E02DE500C090E50230A0E10120A0E115\r
+S315000144200C10A0E104E09DE4700C00EA0030A0E36A\r
+S31500014430000051E3003080E5013083120030801521\r
+S315000144400EF0A0E10EF0A0E10130A0E3003080E51E\r
+S315000144500EF0A0E10030A0E3003080E50EF0A0E10F\r
+S31500014460003090E50120A0E3000053E30030A0E313\r
+S315000144700230A001002080050300A0E10EF0A0E1BA\r
+S31500014480000090E50EF0A0E104402DE500300FE1BB\r
+S3150001449000400FE1C04084E304F029E10120A0E3DC\r
+S315000144A0003081E5002080E51000BDE80EF0A0E1B6\r
+S315000144B00030A0E304402DE5003080E500300FE137\r
+S315000144C0C04001E2C030C3E3043083E103F029E1D7\r
+S315000144D01000BDE80EF0A0E144309FE50DC0A0E15B\r
+S315000144E00510A0E310D82DE938209FE5001083E5DB\r
+S315000144F034309FE50040A0E10000A0E3000082E522\r
+S3150001450004B04CE2004083E520309FE5000083E5DE\r
+S31500014510140094E50FE0A0E110F094E5680200EBC9\r
+S31500014520FAFFFFEA088A0200108A02000C8A0200DA\r
+S31500014530F42002000DC0A0E1F0D82DE904B04CE250\r
+S3150001454008C09BE50C409BE50060A0E104E08CE01F\r
+S315000145500050A0E300C086E508C086E51C0080E2A5\r
+S31500014560102086E5143086E50120A0E10CE086E501\r
+S31500014570044086E50610A0E1185086E504709BE527\r
+S315000145803F0700EB8C309FE54C4086E2001093E537\r
+S3150001459084209FE50400A0E10430A0E1741E00EB35\r
+S315000145A078109FE50430A0E3B000D1E10120A0E33B\r
+S315000145B001C080E2286084E5383086E53C2086E546\r
+S315000145C07C5086E5405086E5785086E50630A0E1C8\r
+S315000145D0B0C0C1E1042082E2B804C6E10510A0E141\r
+S315000145E0012052E2801083E5043083E2FBFFFF5A8B\r
+S315000145F00600A0E1987086E55E2D00EB0610A0E1AD\r
+S315000146001C009FE5E10500EB0600A0E10610A0E114\r
+S31500014610F0681BE9422D00EA6421020018530100EB\r
+S31500014620EC200200148A02000DC0A0E1F0D82DE9A9\r
+S3150001463004B04CE208C09BE50C409BE50060A0E19C\r
+S3150001464004E08CE00050A0E300C086E508C086E5E2\r
+S315000146501C0080E2102086E5143086E50120A0E1E9\r
+S315000146600CE086E5044086E50610A0E1185086E5D3\r
+S3150001467004709BE5020700EB8C309FE54C4086E217\r
+S31500014680001093E584209FE50400A0E10430A0E139\r
+S31500014690371E00EB78109FE50430A0E3B000D1E1AE\r
+S315000146A00120A0E301C080E2286084E5383086E578\r
+S315000146B03C2086E57C5086E5405086E5785086E5C7\r
+S315000146C00630A0E1B0C0C1E1042082E2B804C6E12F\r
+S315000146D00510A0E1012052E2801083E5043083E257\r
+S315000146E0FBFFFF5A0600A0E1987086E5212D00EB3D\r
+S315000146F00610A0E11C009FE5A40500EB0600A0E161\r
+S315000147000610A0E1F0681BE9052D00EA642102000C\r
+S3150001471018530100EC200200148A02000DC0A0E12A\r
+S3150001472030D82DE90050A0E10CD04DE204B04CE2A6\r
+S315000147304C0080E2B61E00EB0510A0E138009FE5B3\r
+S31500014740930500EB343095E598C095E5000053E3F9\r
+S3150001475000E095E5044095E5301095152410950582\r
+S31500014760102095E5143095E50500A0E100508DE88F\r
+S3150001477008408DE5ABFFFFEB30A81BE9148A020068\r
+S315000147800DC0A0E110D82DE90040A0E104B04CE233\r
+S31500014790B4009FE50410A0E17D0500EBAC309FE578\r
+S315000147A0002093E5012082E2002083E5A0309FE509\r
+S315000147B0001093E50300A0E19C2091E5040052E17D\r
+S315000147C01900000A003090E50210A0E1030052E151\r
+S315000147D0F8FFFF1A74209FE5003092E5010053E2CD\r
+S315000147E0000082150E00000A0030A0E34C0084E2AE\r
+S315000147F0B834C4E1021E00EB1C0094E51C1084E2EF\r
+S31500014800010050E110A81B09043091E5043080E550\r
+S31500014810042091E5041081E5000082E51C1084E581\r
+S3150001482010A81BE9450600EBEEFFFFEA20009FE515\r
+S315000148309C3094E5002090E59C3081E5040052E12E\r
+S315000148409C30940500308005E1FFFFEA148A0200DE\r
+S31500014850F4200200E82002000DC0A0E110D82DE9E5\r
+S315000148600040A0E104B04CE2B4009FE50410A0E1D1\r
+S31500014870470500EBAC309FE5002093E5012082E27D\r
+S31500014880002083E5A0309FE5001093E50300A0E139\r
+S315000148909C2091E5040052E11900000A003090E5E0\r
+S315000148A00210A0E1030052E1F8FFFF1A74209FE510\r
+S315000148B0003092E5010053E2000082150E00000A65\r
+S315000148C00030A0E34C0084E2B834C4E1CC1D00EB17\r
+S315000148D01C0094E51C1084E2010050E110A81B099C\r
+S315000148E0043091E5043080E5042091E5041081E56A\r
+S315000148F0000082E51C1084E510A81BE90F0600EBF9\r
+S31500014900EEFFFFEA20009FE59C3094E5002090E54C\r
+S315000149109C3081E5040052E19C309405003080050D\r
+S31500014920E1FFFFEA148A0200F4200200E8200200F7\r
+S315000149300DC0A0E130D82DE95C309FE504B04CE212\r
+S31500014940004093E554509FE5003095E5013083E240\r
+S31500014950003085E5383094E544009FE5000053E3D7\r
+S315000149600410A0E10900000A013083E3383084E530\r
+S31500014970003095E5013053E20300A0E100308515D2\r
+S315000149800000000A30A81BE9EC0500EBFCFFFFEA7A\r
+S31500014990BE0400EB383094E5F2FFFFEA0C8A020010\r
+S315000149A0F4200200148A02000DC0A0E130D82DE9DE\r
+S315000149B004B04CE20040A0E180309FE5002093E581\r
+S315000149C0012082E2002083E5383090E51C5080E228\r
+S315000149D0030013E30320C3E30900000A382080E53E\r
+S315000149E00C3095E50010A0E1000053E20F00001A1B\r
+S315000149F0383094E50410A0E1000053E340009FE540\r
+S31500014A000800000A34209FE5003092E5013053E2A8\r
+S31500014A100300A0E1003082150000000A30A81BE95E\r
+S31500014A20C60500EBFCFFFFEA750400EBF4FFFFEAA5\r
+S31500014A309F0500EB0030A0E30C3085E5EBFFFFEAB4\r
+S31500014A40F4200200148A02000DC0A0E110D82DE95D\r
+S31500014A5004B04CE284C09FE500409CE580209FE5C0\r
+S31500014A60003092E5013083E2003082E5400094E5B2\r
+S31500014A70000050E3013040E20E00000A403084E5B8\r
+S31500014A805C209FE5003092E5013053E20300A0E18E\r
+S31500014A90003082150500000A7C3094E5053043E2BA\r
+S31500014AA0010053E310A81B8910681BE9040100EA01\r
+S31500014AB0A20500EBF7FFFFEA00109CE50130A0E339\r
+S31500014AC0783081E500209CE57C0082E597FFFFEBCD\r
+S31500014AD0383094E5023083E3383084E5E7FFFFEAB6\r
+S31500014AE00C8A0200F42002000DC0A0E1F0DF2DE9DE\r
+S31500014AF0E8809FE504B04CE204D04DE20170A0E1EC\r
+S31500014B000060A0E1005098E5D4A09FE500309AE549\r
+S31500014B10013083E200308AE5404095E50390A0E349\r
+S31500014B20003054E2012044E20E00000A402085E5EF\r
+S31500014B30AC209FE5003092E5013053E20300A0E18D\r
+S31500014B40003082150500000A7C3095E5053043E208\r
+S31500014B50010053E3F0AF1B89F06F1BE9D80000EAAF\r
+S31500014B60760500EBF7FFFFEA78209FE5000092E566\r
+S31500014B70060090E900C098E5061091E078908CE572\r
+S31500014B80000098E50720A2E07C4080E5000098E55A\r
+S31500014B9000408DE54C0080E2371D00EB7C3095E549\r
+S31500014BA0000053E3E1FFFF1A003098E5789083E5B2\r
+S31500014BB0002098E57C4082E55CFFFFEB383095E507\r
+S31500014BC000009AE5023083E3383085E55B0500EBAA\r
+S31500014BD0000098E54C0080E28D1D00EBD3FFFFEA53\r
+S31500014BE00C8A0200F4200200642102000DC0A0E13B\r
+S31500014BF000D82DE904B04CE25C309FE5002093E536\r
+S31500014C00012082E2002083E5383090E5020013E3BB\r
+S31500014C104030900501308302403080050800001ABB\r
+S31500014C2034209FE5003092E5013053E20300A0E114\r
+S31500014C30003082150000000A00A81BE93F0500EBC1\r
+S31500014C40FCFFFFEA0730A0E30020A0E37C3080E50B\r
+S31500014C50782080E553FFFFEBF0FFFFEAF420020026\r
+S31500014C600DC0A0E110D82DE904B04CE238209FE533\r
+S31500014C70003092E5013083E2003082E50030A0E3A6\r
+S31500014C80404090E5403080E5003092E5013053E246\r
+S31500014C900300A0E1003082150100000A0400A0E132\r
+S31500014CA010A81BE9250500EBFBFFFFEAF420020033\r
+S31500014CB00DC0A0E130D82DE904B04CE20040A0E1DE\r
+S31500014CC05C509FE5003095E5013083E2003085E5D3\r
+S31500014CD03C3090E5382090E5013083E2000052E354\r
+S31500014CE040009FE50410A0E13C3084E50900000A7C\r
+S31500014CF0043082E3383084E5003095E5013053E233\r
+S31500014D000300A0E1003085150000000A30A81BE968\r
+S31500014D100A0500EBFCFFFFEADC0300EB382094E513\r
+S31500014D20F2FFFFEAF4200200148A02000DC0A0E19E\r
+S31500014D3000D82DE904B04CE200C0A0E170209FE547\r
+S31500014D40003092E5013083E2003082E53C3090E5A7\r
+S31500014D50010053E30B00000A000053E3013043E274\r
+S31500014D603C30801548209FE5003092E5013053E242\r
+S31500014D700300A0E1003082150000000A00A81BE92B\r
+S31500014D80EE0400EBFCFFFFEA382090E50030A0E3DB\r
+S31500014D900420C2E3030052E10010A0E13C3080E5AB\r
+S31500014DA038208CE50C009FE5EDFFFF1A940300EB1C\r
+S31500014DB0EBFFFFEAF4200200148A02000DC0A0E115\r
+S31500014DC000D82DE904B04CE200C0A0E164309FE5B3\r
+S31500014DD0002093E5012082E2002083E53C3090E546\r
+S31500014DE0000053E30800000A382090E50030A0E3F4\r
+S31500014DF00420C2E3030052E10010A0E13C3080E54B\r
+S31500014E0038208CE530009FE50800000A24209FE544\r
+S31500014E10003092E5013053E20300A0E10030821533\r
+S31500014E200000000A00A81BE9C40400EBFCFFFFEA2E\r
+S31500014E30730300EBF4FFFFEAF4200200148A020078\r
+S31500014E400DC0A0E100D82DE904B04CE26C309FE51D\r
+S31500014E50002093E5012082E2002083E5783090E589\r
+S31500014E60070053E303F19F970B0000EAA04E0100F0\r
+S31500014E708C4E01008C4E01008C4E0100A04E0100AB\r
+S31500014E80A04E0100A04E0100A04E01000030A0E39B\r
+S31500014E900420A0E3783080E57C2080E5C1FEFFEBAD\r
+S31500014EA018209FE5003092E5010053E200008215CB\r
+S31500014EB00000000A00A81BE9A00400EBFCFFFFEAC2\r
+S31500014EC0F42002000DC0A0E130D82DE948209FE56D\r
+S31500014ED004B04CE2004092E540509FE5003095E574\r
+S31500014EE0013083E2003085E5000092E54C0080E266\r
+S31500014EF0C71C00EB383094E524009FE5100053E30E\r
+S31500014F000410A0E11030A013383084155F03001B94\r
+S31500014F10000095E530681BE9880400EA0C8A020066\r
+S31500014F20F4200200148A02000DC0A0E110D82DE978\r
+S31500014F30D4309FE504B04CE2002093E50040A0E1A7\r
+S31500014F40020050E12E00000AC0209FE5003092E5E4\r
+S31500014F50013083E2003082E50400A0E196FFFFEB19\r
+S31500014F604C0084E2AA1C00EB7C3094E5060053E376\r
+S31500014F701000000A783094E5070053E303F19F9788\r
+S31500014F800C0000EAA44F0100F04F0100F04F0100B0\r
+S31500014F90F04F0100C04F0100C04F0100C04F01009A\r
+S31500014FA0C04F0100383094E5000053E30B00000ABE\r
+S31500014FB01030A0E3383084E50400A0E179FEFFEB70\r
+S31500014FC048209FE5003092E5010053E2000082157A\r
+S31500014FD00000000A10A81BE9580400EBFCFFFFEAD9\r
+S31500014FE00410A0E128009FE5280300EBEFFFFFEA8C\r
+S31500014FF00030A0E30620A0E3783084E57C2084E538\r
+S31500015000ECFFFFEAAEFFFFEBCEFFFFEA0C8A0200E0\r
+S31500015010F4200200148A02000DC0A0E1F0D92DE9A6\r
+S3150001502004B04CE20040A0E10150A0E110219FE54F\r
+S31500015030003092E5013083E2003082E5383090E5B8\r
+S315000150400070A0E3070053E13800000A010013E3F2\r
+S315000150503400000A1C6080E20C7096E5000057E3FC\r
+S315000150603000000A0700A0E10410A0E1100400EBE3\r
+S31500015070D0809FE50030A0E30C3086E50800A0E172\r
+S315000150800410A0E1420300EB343094E5000053E341\r
+S315000150900300000A243094E5305084E5050053E10D\r
+S315000150A0000000DA245084E50800A0E10410A0E124\r
+S315000150B0360300EB383094E5000053E31500000A8F\r
+S315000150C0010013E30300000A000057E30700A011E3\r
+S315000150D00410A011D103001B6C309FE5002093E55D\r
+S315000150E0020054E164309F050120A00300208305DE\r
+S315000150F00400A0110E03001B44209FE5003092E539\r
+S31500015100010053E2000082150000000AF0A91BE924\r
+S315000151100A0400EBFCFFFFEA0800A0E10410A0E18D\r
+S31500015120B70200EBEBFFFFEA18809FE5D2FFFFEA2B\r
+S3150001513010809FE50010A0E10800A0E1D30200EB7A\r
+S31500015140CDFFFFEAF4200200148A02000C8A020055\r
+S31500015150108A02000DC0A0E1F0D92DE904B04CE29D\r
+S3150001516004D04DE20080A0E10260A0E10150A0E17F\r
+S3150001517094709FE5003097E5013083E2003087E5C2\r
+S31500015180EAFDFFEB84309FE584C09FE5000093E5CF\r
+S315000151900230A0E3060090E900E09CE50040A0E3B0\r
+S315000151A078308EE500009CE5051091E07C4080E5B5\r
+S315000151B000009CE50620A2E00430A0E14C0080E25C\r
+S315000151C000408DE5AC1B00EB003097E5013053E262\r
+S315000151D00300A0E1003087150900000A30309FE581\r
+S315000151E0000093E54C0080E2091C00EB7C3098E559\r
+S315000151F0053043E2010053E3F0A91B89F0691BE97D\r
+S315000152002FFFFFEACD0300EBF3FFFFEAF4200200D4\r
+S31500015210642102000C8A02001CC09FE510402DE9A2\r
+S3150001522000409CE50030A0E1040053E10C009FE53D\r
+S315000152301080BD181040BDE8EB0000EA0C8A0200A0\r
+S31500015240F08902000DC0A0E170D82DE904B04CE24E\r
+S3150001525060509FE5003095E5013083E2003085E539\r
+S3150001526054409FE50020E0E3003094E5000053E25E\r
+S315000152700100001A0200A0E170A81BE9481700EB23\r
+S31500015280003094E50120A0E31230C3E10060A0E103\r
+S31500015290003084E5003095E5013053E20300A0E1DA\r
+S315000152A0003085150100000A0620A0E1F0FFFFEAA3\r
+S315000152B0A20300EBFBFFFFEAF4200200F02002004C\r
+S315000152C00DC0A0E100D82DE904B04CE23CC09FE539\r
+S315000152D000309CE5013083E200308CE530109FE51B\r
+S315000152E00120A0E3003091E5123083E1003081E531\r
+S315000152F000309CE5013053E20300A0E100308C153B\r
+S315000153000000000A00A81BE98C0300EBFCFFFFEA82\r
+S31500015310F4200200F02002000DC0A0E100D82DE922\r
+S3150001532004B04CE2280091E57C209FE5003092E52F\r
+S31500015330013083E2003082E5783090E5070053E3DF\r
+S3150001534003F19F970B0000EA7C5301007C53010097\r
+S31500015350685301009C5301007C5301007C530100FA\r
+S315000153607C5301007C5301000030A0E30720A0E339\r
+S31500015370783080E57C2080E58AFDFFEB28209FE5DB\r
+S31500015380003092E5010053E2000082150000000A98\r
+S3150001539000A81BE9690300EBFCFFFFEA0030A0E36C\r
+S315000153A0783080E50320A0E3F1FFFFEAF420020054\r
+S315000153B00C209FE5003092E5013083E2003082E562\r
+S315000153C0FBFFFFEA4C8902000DC0A0E130D82DE9B0\r
+S315000153D064409FE504B04CE2004064E0C442A0E1B1\r
+S315000153E0843084E0033283E0033483E0033883E0CE\r
+S315000153F048C09FE548E09FE50CD04DE2034184E0BB\r
+S3150001540084E58EE000C08DE538209FE502CBA0E360\r
+S315000154101F10A0E30030A0E30050A0E104E08DE5F9\r
+S3150001542008C08DE542FCFFEB1C009FE50510A0E1DD\r
+S315000154300420A0E130681BE94D0200EA5089020010\r
+S315000154401C1202004C810200B0530100148A0200B2\r
+S315000154500DC0A0E130D82DE964409FE504B04CE2CF\r
+S31500015460004064E0C442A0E1843084E0033283E07A\r
+S31500015470033483E0033883E048C09FE548E09FE5B5\r
+S315000154800CD04DE2034184E084E58EE000C08DE559\r
+S3150001549038209FE502CBA0E31F10A0E30030A0E374\r
+S315000154A00050A0E104E08DE508C08DE520FCFFEB8E\r
+S315000154B01C009FE50510A0E10420A0E130681BE96E\r
+S315000154C02B0200EA508902001C1202004C810200E4\r
+S315000154D0B0530100148A02000DC0A0E170D82DE975\r
+S315000154E058609FE504B04CE2060051E1010050030B\r
+S315000154F00050A0E10140A0E10D00000A060054E1C0\r
+S315000155000000550370A81B1934009FE5000050E305\r
+S3150001551070A81B090050A0E1A04080E2050054E1FB\r
+S31500015520A04044E20400A0E170A81B0993FCFFEB34\r
+S31500015530F9FFFFEA08009FE5C4FFFFEBEEFFFFEA74\r
+S31500015540983A00005089020004E02DE508109FE515\r
+S315000155500100A0E304E09DE4DEFFFFEA983A0000C3\r
+S3150001556004E02DE508109FE50000A0E304E09DE4BA\r
+S31500015570D8FFFFEA983A00000EF0A0E108209FE567\r
+S315000155800030A0E30C0080E80EF0A0E178550100A0\r
+S3150001559008209FE50030A0E30C0080E80EF0A0E1B2\r
+S315000155A07855010004E02DE504E09DE50310A0E136\r
+S315000155B000005EE30030901508C09DE500308E15B1\r
+S315000155C000005CE30430901500308C15041080E572\r
+S315000155D0002080E504F09DE408209FE50030A0E36B\r
+S315000155E00C0080E80EF0A0E1785501000DC0A0E1A5\r
+S315000155F000D82DE90030A0E104B04CE2040090E5AA\r
+S315000156000FE0A0E100F093E500A81BE904E02DE519\r
+S3150001561014309FE500C0A0E1000093E50120A0E160\r
+S315000156200C10A0E104E09DE4FAFEFFEA0C8A0200F8\r
+S315000156301C309FE50020A0E1030051E10100520367\r
+S3150001564004E02DE50C009FE504F09D1404E09DE4C3\r
+S31500015650CEFFFFEAE02E0000F089020004E02DE50E\r
+S3150001566008109FE50100A0E304E09DE4EFFFFFEAD7\r
+S31500015670E02E0000060080E804109DE500209DE56F\r
+S3150001568000C0A0E314C080E5082080E50C1080E589\r
+S31500015690103080E518C080E50EF0A0E1060080E834\r
+S315000156A004109DE500209DE500C0A0E314C080E53F\r
+S315000156B0082080E50C1080E5103080E518C080E5F3\r
+S315000156C00EF0A0E104E02DE504E09DE47D0000EA92\r
+S315000156D004E02DE504E09DE47A0000EA0DC0A0E1B6\r
+S315000156E070D82DE96C509FE50060A0E3063195E77F\r
+S315000156F004B04CE2060053E170A81B0900000FE15B\r
+S3150001570000400FE1C04084E304F029E100C095E5C3\r
+S315000157100020A0E318309CE5063185E714109CE5CE\r
+S3150001572014208CE500300FE1C04000E2C030C3E335\r
+S31500015730043083E103F029E100009CE510209CE59B\r
+S315000157400FE0A0E10CF09CE5003095E5000053E385\r
+S3150001575070A81B09E8FFFFEA048A020004E02DE5B0\r
+S3150001576004E09DE4DCFFFFEA04E02DE504E09DE4AE\r
+S3150001577060C5FFEA04402DE500100FE100400FE18E\r
+S31500015780C04084E304F029E1143090E538C09FE578\r
+S31500015790013083E2143080E5142090E5010052E3E4\r
+S315000157A000209C050030A0031820800503018C070A\r
+S315000157B000300FE1C04001E2C030C3E3043083E1B1\r
+S315000157C003F029E11000BDE80EF0A0E1048A020011\r
+S315000157D004E02DE504E09DE4E5FFFFEAA000A0E179\r
+S315000157E0010000E2000051E30000A00301000012E5\r
+S315000157F00DC0A0E1000050E310D82DE90100A0E1A1\r
+S3150001580004B04CE20240A0E10F00001A40309FE5CF\r
+S31500015810002093E5184082E538209FE5003092E5A7\r
+S31500015820013053E20300A0E1003082150400000AB2\r
+S315000158301C309FE50020A0E3001093E5182081E5C8\r
+S3150001584010A81BE93D0200EBF8FFFFEAC8FFFFEBDA\r
+S31500015850EDFFFFEA0C8A0200F42002000DC0A0E170\r
+S3150001586010D82DE90040A0E1041094E5000090E570\r
+S3150001587004B04CE2791600EB001094E534009FE584\r
+S3150001588034309FE5012190E7030052E110A81B196E\r
+S31500015890083094E5013180E7000094E5102094E595\r
+S315000158A018309FE5002183E7001094E510309FE54D\r
+S315000158B0014183E710A81BE904140200A821010095\r
+S315000158C0081502000C160200001090E538C09FE58D\r
+S315000158D0082090E501319CE704E02DE5020053E143\r
+S315000158E000E0A0E304F09D1420309FE501318CE730\r
+S315000158F0002090E518309FE502E183E7001090E56E\r
+S3150001590010309FE501E183E704F09DE404140200F1\r
+S31500015910A8210100081502000C16020008309FE5B7\r
+S31500015920002193E7002081E50EF0A0E120000000B0\r
+S3150001593010402DE900C00FE100400FE1C04084E3B3\r
+S3150001594004F029E128E09FE5000052E300319E17AB\r
+S315000159501CE09F050030821500118EE700300FE133\r
+S31500015960C0400CE2C030C3E3043083E103F029E117\r
+S315000159701080BDE82000000004402DE544009FE5AD\r
+S3150001598000C0A0E30C3190E70C0053E10800001AB7\r
+S3150001599000200FE100400FE1C04084E304F029E15B\r
+S315000159A024309FE50110A0E3002083E51C309FE52C\r
+S315000159B0001083E5003090E5013083E20C3180E789\r
+S315000159C01000BDE80EF0A0E1F8890200008A02008D\r
+S315000159D0FC89020004402DE544109FE50020A0E368\r
+S315000159E0023191E7013043E2023181E7022191E779\r
+S315000159F0000052E30800001A28309FE528109FE5B1\r
+S31500015A00002083E5022191E700300FE1C04002E268\r
+S31500015A10C030C3E3043083E103F029E11000BDE89F\r
+S31500015A200EF0A0E1F8890200FC890200008A02005A\r
+S31500015A300DC0A0E130D82DE904B04CE200500FE1D1\r
+S31500015A4000400FE1C04084E304F029E1EB1500EBCF\r
+S31500015A5000300FE1C04005E2C030C3E3043083E10A\r
+S31500015A6003F029E130A81BE904E02DE504E09DE4FB\r
+S31500015A70E21500EA0DC0A0E130D82DE904B04CE2F0\r
+S31500015A8000500FE100400FE1C04084E304F029E13A\r
+S31500015A90E51500EB00300FE1C04005E2C030C3E37D\r
+S31500015AA0043083E103F029E130A81BE904E02DE588\r
+S31500015AB004E09DE4DC1500EA04E02DE504E09DE444\r
+S31500015AC0E41500EA04E02DE504E09DE4E21500EAB0\r
+S31500015AD014309FE5030051E1010050030C309F058E\r
+S31500015AE00020A003002083050EF0A0E1E02E0000B7\r
+S31500015AF0FC89020004E02DE508109FE50100A0E302\r
+S31500015B0004E09DE4F1FFFFEAE02E000004E02DE54C\r
+S31500015B1008109FE50000A0E304E09DE4EBFFFFEA27\r
+S31500015B20E02E000044309FE50120A0E3002083E53C\r
+S31500015B30042080E21F30A0E30010A0E3013043E21D\r
+S31500015B40010073E3041082E4FBFFFF1A20309FE596\r
+S31500015B500020A0E30110A0E3002080E5021183E705\r
+S31500015B6010309FE50500A0E3020183E70EF0A0E1F6\r
+S31500015B70F4200200108A0200088A020044309FE5E0\r
+S31500015B800120A0E3002083E5042080E21F30A0E38A\r
+S31500015B900010A0E3013043E2010073E3041082E444\r
+S31500015BA0FBFFFF1A20309FE50020A0E30110A0E3D0\r
+S31500015BB0002080E5021183E710309FE50500A0E390\r
+S31500015BC0020183E70EF0A0E1F4200200108A020030\r
+S31500015BD0088A02000DC0A0E110D82DE90040A0E11D\r
+S31500015BE004B04CE2000090E5ED1400EB004184E0C6\r
+S31500015BF0043094E5000053E31C0043E20300A001D6\r
+S31500015C0010A81BE90DC0A0E1F0D92DE9247091E59A\r
+S31500015C10283091E5074180E0000053E304B04CE2EF\r
+S31500015C200160A0E10050A0E1048084E21400001AA2\r
+S31500015C30043094E5000053E3003095050120A003EC\r
+S31500015C401237830100308505001098E5000056E300\r
+S31500015C501C0086120600A001000051E304309115D4\r
+S31500015C600010801504308015042091150000880568\r
+S31500015C7004008115000082150600A0E1F0691BE908\r
+S31500015C802B0000EA0300A0E1090100EBE7FFFFEAB0\r
+S31500015C9010402DE9244091E5000051E3043180E0F4\r
+S31500015CA004E083E21CC0811201C0A00100109EE540\r
+S31500015CB001005CE100309C1504209C15042083152D\r
+S31500015CC004109C1504C08C150030811500C08C157C\r
+S31500015CD000109E150500000A000051E300309005F2\r
+S31500015CE00120A0031234C301003080051080BDE8F5\r
+S31500015CF0000051E3F7FFFF0A00C091E501005CE1F6\r
+S31500015D000030A0030310A00100308E05F1FFFF0A49\r
+S31500015D10043091E504308CE5042091E5041081E519\r
+S31500015D2000C082E5001081E50C10A0E100C08EE5FF\r
+S31500015D30E8FFFFEA30C09FE5241090E500209CE5CE\r
+S31500015D40243092E5010053E1030000CA00309CE5CE\r
+S31500015D50382093E5000052E30EF0A0010C309FE5D8\r
+S31500015D600120A0E3002083E50EF0A0E10C8A0200E9\r
+S31500015D70108A020004E02DE50C309FE50100A0E148\r
+S31500015D80021183E704E09DE4E7FBFFEA0C8A0200C7\r
+S31500015D900EF0A0E10EF0A0E10100A0E30EF0A0E1FB\r
+S31500015DA004E02DE518209FE5003092E5013043E23D\r
+S31500015DB0000053E3003082E504F09D1404E09DE405\r
+S31500015DC0000000EA088A020004E02DE56C309FE538\r
+S31500015DD000C0A0E30C2193E764309FE50C0052E17B\r
+S31500015DE0001093E504F09D14383091E50C0053E161\r
+S31500015DF004F09D14242091E548309FE50CE0A0E1D4\r
+S31500015E00020183E0042090E50C0052E10300000A40\r
+S31500015E10003092E5002053E2043080E51CE0421296\r
+S31500015E2001005EE120309F150120A013002083159B\r
+S31500015E3008309FE50520A0E30C2183E704F09DE4EB\r
+S31500015E40088A02000C8A0200148A0200108A0200E3\r
+S31500015E5004E02DE504009FE504E09DE4D9FFFFEA97\r
+S31500015E60148A0200030080E9000080E50EF0A0E13B\r
+S31500015E70030080E9000080E50EF0A0E104E02DE5D5\r
+S31500015E8074209FE5003092E5013083E2003082E51F\r
+S31500015E901C0040E2383090E5000053E31100001A7F\r
+S31500015EA0242090E554309FE5021183E0042091E51A\r
+S31500015EB0000052E30400000A003092E5002053E29C\r
+S31500015EC01CC042E2043081E50000001A02C0A0E1D4\r
+S31500015ED000005CE128309F1528309F050120A013A2\r
+S31500015EE00520A003002083E50C309FE5000093E523\r
+S31500015EF0010040E204E09DE4900000EAF420020083\r
+S31500015F00148A0200108A0200088A02000DC0A0E16C\r
+S31500015F1000D82DE904B04CE254209FE5003092E50B\r
+S31500015F20013083E2003082E548309FE5002183E0BD\r
+S31500015F30043092E5000053E30400000A0030931593\r
+S31500015F400430821530309FE50120A0E3002083E56F\r
+S31500015F501C209FE5003092E5013053E20300A0E1E9\r
+S31500015F60003082150000000A00A81BE9730000EB4F\r
+S31500015F70FCFFFFEAF4200200148A0200108A0200E4\r
+S31500015F800DC0A0E100D82DE904B04CE200C0A0E1AB\r
+S31500015F9080209FE5003092E5013083E2003082E502\r
+S31500015FA00C1090E51C2040E2000051E30C00000AB1\r
+S31500015FB0000052E30030A0110030A003003081E55B\r
+S31500015FC050209FE5003092E5013053E20300A0E145\r
+S31500015FD0003082150000000A00A81BE9570000EBFB\r
+S31500015FE0FCFFFFEA003090E50200A0E10C0053E15E\r
+S31500015FF0F2FFFF0A000052E3243092E518209FE5E4\r
+S315000160000C10A0110010A003032182E0041082E508\r
+S3150001601047FFFFEBE9FFFFEAF4200200148A0200C2\r
+S3150001602004E02DE500C090E5000051E31CE081E2AB\r
+S3150001603001E0A00100005CE304309C1500C08E1550\r
+S3150001604004308E1504209C1500E0800504E08C15B3\r
+S3150001605000E08215280081E504F09DE400C0A0E17E\r
+S31500016060000090E5000050E30020A0010B00000AAB\r
+S31500016070001090E5000051E1043090150030A003B6\r
+S31500016080043081150420901500308C05001082150E\r
+S315000160901C2040E2040080150000801500108C15BC\r
+S315000160A0000052E30030A0130200A0E1283082155F\r
+S315000160B00EF0A0E10030A0E3283081E5003090E544\r
+S315000160C0000051E31CC081E201C0A00103005CE1B4\r
+S315000160D000309C1504209C150420831504109C1582\r
+S315000160E004C08C150030811500C08C150EF0A0116E\r
+S315000160F000005CE30EF0A00100109CE50C0051E1EC\r
+S3150001610004309C150030A0030430811504209C1531\r
+S31500016110003080050010821504C08C1500C08C1556\r
+S31500016120001080150EF0A0E1000090E5000050E39C\r
+S315000161301C3040E20030A0010300A0E10EF0A0E116\r
+S315000161400DC0A0E170D82DE904B04CE20050A0E1E9\r
+S31500016150000055E30300001AB8309FE5052193E7D7\r
+S31500016160000052E32900001AAC609FE5004096E565\r
+S31500016170383094E5000053E30300001A9C309FE594\r
+S31500016180002093E5000052E31100000A90009FE50C\r
+S315000161908FFEFFEB000054E10700000A84209FE513\r
+S315000161A00C0080E2003092E50C1084E2013083E2BB\r
+S315000161B0003082E58D1300EB004086E568309FE5EF\r
+S315000161C00520A0E3002083E550309FE50010A0E301\r
+S315000161D0001083E5000055E30900001A4C109FE505\r
+S315000161E0005081E52C309FE5052193E7000052E33D\r
+S315000161F000309115013083120030811570A81B09FA\r
+S31500016200D2FFFFEA24309FE5005083E570A81BE921\r
+S3150001621054FDFFEBD3FFFFEA048A02000C8A020059\r
+S31500016220108A0200148A0200988A0200088A020073\r
+S31500016230F42002000DC0A0E100D82DE904B04CE223\r
+S31500016240FFFFFFEB0DC0A0E100D82DE924009FE57B\r
+S3150001625004B04CE25EFEFFEB1C309FE51C209FE57F\r
+S3150001626000C0A0E10010A0E3001083E50C0080E26D\r
+S3150001627000C082E5641300EB148A0200108A020052\r
+S315000162800C8A02000DC0A0E110D82DE90210A0E190\r
+S3150001629004B04CE20040A0E1F1FEFFEB0030A0E3C8\r
+S315000162A0183084E50C3084E5103084E510A81BE92C\r
+S315000162B00DC0A0E110D82DE90210A0E104B04CE216\r
+S315000162C00040A0E1E6FEFFEB0030A0E3183084E5D4\r
+S315000162D00C3084E5103084E510A81BE90DC0A0E15F\r
+S315000162E070D82DE9086090E50050A0E1060051E163\r
+S315000162F004B04CE21C0040E270A81BA90030A0E3E8\r
+S31500016300184095E5183085E542FBFFEB000054E3A4\r
+S315000163100130A0E314608505183085E570A81BE9F6\r
+S3150001632004E02DE5003092E50120A0E1000053E3F1\r
+S3150001633004F09D04241091E504E09DE4E6FFFFEAE4\r
+S3150001634010402DE9104090E500C0A0E1000054E3A3\r
+S315000163501C0040E21080BD1818309CE5000053E394\r
+S315000163601080BD0814209CE508309CE50210A0E1D0\r
+S31500016370020053E118408CE51080BDA81040BDE82D\r
+S3150001638024FBFFEA04E02DE50120A0E1241091E5BC\r
+S3150001639004E09DE4D0FFFFEA04E02DE504E09DE47E\r
+S315000163A0DEFFFFEA04E02DE504E09DE4E3FFFFEAFA\r
+S315000163B004E02DE50020A0E304E09DE4C6FFFFEA2A\r
+S315000163C004E02DE504E09DE4DCFFFFEA0DC0A0E159\r
+S315000163D070D82DE958609FE504B04CE2060051E102\r
+S315000163E0010050030050A0E10140A0E10D00000AA8\r
+S315000163F0060054E10000550370A81B1934009FE5FF\r
+S31500016400040070E370A81B09045080E2844080E216\r
+S31500016410040055E1044044E20400A0E170A81B0910\r
+S31500016420F92500EBF9FFFFEA08009FE5BCFDFFEB4C\r
+S31500016430EEFFFFEAF82A0000148A020004E02DE5C7\r
+S3150001644008109FE50100A0E304E09DE4DEFFFFEAFA\r
+S31500016450F82A000004E02DE508109FE50000A0E3FE\r
+S3150001646004E09DE4D8FFFFEAF82A00000030A0E32B\r
+S315000164700A0080E80EF0A0E10030A0E30A0080E8FF\r
+S315000164800EF0A0E104E02DE5040080E204E09DE4C5\r
+S31500016490DD2500EA04E02DE5040080E204E09DE448\r
+S315000164A0D92500EA0DC0A0E1F0DF2DE9D4109FE562\r
+S315000164B004B04CE20040A0E101A0A0E3006091E538\r
+S315000164C0C4209FE5003092E50A3083E0003082E582\r
+S315000164D0002090E5000052E31C00001A0180A0E1B3\r
+S315000164E0047080E20A90A0E1002098E50050A0E344\r
+S315000164F0789082E5003098E57C5083E50BF9FFEB57\r
+S315000165000700A0E10610A0E1C4FEFFEB78309FE58D\r
+S31500016510000093E509FFFFEB7C3096E5040053E3A9\r
+S31500016520040000BA050053E305A0A0D1010000DA7A\r
+S31500016530060053E31100000A002094E5000052E32F\r
+S315000165400030A01301300A02000053E3E5FFFF1AF1\r
+S3150001655000005AE3013042120030841528209FE5DD\r
+S31500016560003092E5010053E2000082150100000AA5\r
+S315000165700A00A0E1F0AF1BE9F0FEFFEBFBFFFFEA2B\r
+S315000165804FFAFFEBEBFFFFEA0C8A0200F420020050\r
+S315000165900DC0A0E1F0DD2DE944419FE504B04CE2D8\r
+S315000165A004D04DE20060A0E1005094E50170A0E343\r
+S315000165B030019FE5003090E5073083E0003080E54B\r
+S315000165C0000094E50330A0E3783080E500E094E52F\r
+S315000165D000C0A0E37CC08EE5000094E50C30A0E18C\r
+S315000165E04C0080E200C08DE5A31600EB7C3095E5FA\r
+S315000165F0000053E3003096050200000A003096E5DC\r
+S31500016600007053E20170A013000053E30030A013A1\r
+S3150001661001300702000053E31E00000AC0809FE517\r
+S31500016620044086E203A0A0E3003098E578A083E564\r
+S31500016630002098E50030A0E37C3082E5BBF8FFEB53\r
+S315000166400400A0E10510A0E174FEFFEB94309FE584\r
+S31500016650000093E5B9FEFFEB7C3095E5033043E29C\r
+S31500016660030053E303F19F97040000EA7C660100EF\r
+S315000166707C6601007C660100DC6601000070A0E317\r
+S31500016680003096E5000053E30030A0130130070205\r
+S31500016690000053E3E3FFFF1A44309FE5000093E552\r
+S315000166A04C0080E2DA1600EB000057E30030961545\r
+S315000166B0013043120030861528209FE5003092E50F\r
+S315000166C0010053E2000082150100000A0700A0E163\r
+S315000166D0F0AD1BE999FEFFEBFBFFFFEAF8F9FFEBD3\r
+S315000166E0E6FFFFEA0C8A0200F42002000DC0A0E1D9\r
+S315000166F010D82DE904B04CE20140A0E344309FE5F7\r
+S31500016700002093E5042082E0002083E5003090E537\r
+S31500016710000053E3013043E2003080C50040A0D3BE\r
+S3150001672020209FE5003092E5013053E20300A0E10D\r
+S31500016730003082150100000A0400A0E110A81BE93F\r
+S315000167407EFEFFEBFBFFFFEAF42002000DC0A0E195\r
+S3150001675030D82DE90010A0E104B04CE264509FE569\r
+S31500016760003095E5013083E2003085E5003090E5A3\r
+S31500016770013083E2043080E4042091E5000052E315\r
+S315000167800040A0130140A003000054E30700000AE3\r
+S31500016790003095E5013053E20300A0E10030851594\r
+S315000167A00000000A30A81BE964FEFFEBFCFFFFEACC\r
+S315000167B029FEFFEB0730A0E37C3080E5784080E5D9\r
+S315000167C078F8FFEBF1FFFFEAF4200200000090E504\r
+S315000167D00EF0A0E10030A0E30A0080E80EF0A0E18F\r
+S315000167E00030A0E30A0080E80EF0A0E10DC0A0E1B0\r
+S315000167F0F0D92DE904B04CE20040A0E178309FE5E4\r
+S31500016800002093E5012082E2002083E5043090E533\r
+S31500016810048080E2000053E30030A0130130A0039E\r
+S31500016820000053E30850A0E10900001A0370A0E13B\r
+S315000168300560A0E30500A0E107FEFFEB7C6080E5B3\r
+S31500016840787080E557F8FFEB043094E5000053E3D8\r
+S31500016850F7FFFF1A20209FE5003092E5010053E281\r
+S31500016860000082150200000A0800A0E1F0691BE998\r
+S31500016870E52400EA31FEFFEBFAFFFFEAF42002000D\r
+S315000168800DC0A0E1F0D92DE904B04CE20040A0E131\r
+S3150001689078309FE5002093E5012082E2002083E520\r
+S315000168A0043090E5048080E2000053E30030A01339\r
+S315000168B00130A003000053E30850A0E10900001ACB\r
+S315000168C00370A0E10560A0E30500A0E1E2FDFFEB96\r
+S315000168D07C6080E5787080E532F8FFEB043094E562\r
+S315000168E0000053E3F7FFFF1A20209FE5003092E5F1\r
+S315000168F0010053E2000082150200000A0800A0E12F\r
+S31500016900F0691BE9C02400EA0CFEFFEBFAFFFFEA7F\r
+S31500016910F42002000DC0A0E100D82DE904B04CE23C\r
+S3150001692034209FE5003092E5013083E2003082E5B4\r
+S31500016930003090E5013003E0003080E5003092E55B\r
+S31500016940013053E20300A0E1003082150000000A85\r
+S3150001695000A81BE9F9FDFFEBFCFFFFEAF4200200AA\r
+S315000169600DC0A0E1F0DD2DE904B04CE204D04DE20A\r
+S315000169700050A0E118219FE5003092E5013083E245\r
+S31500016980003082E5042090E5003090E5000052E3F6\r
+S315000169900020A0130120A003013083E1000052E38F\r
+S315000169A0003080E52700001A24804BE2042028E508\r
+S315000169B0047080E207A0A0E30700A0E1A6FDFFEBBB\r
+S315000169C0444090E500C0A0E1002094E5000052E3B8\r
+S315000169D000E095050300000A00E095E50E3002E0AF\r
+S315000169E0020053E10400000A043094E50C10A0E112\r
+S315000169F00E0013E10800A0E12300000A0060A0E3F5\r
+S31500016A007CA08CE50C00A0E178608CE5E5F7FFEB56\r
+S31500016A100C3094E5002095E5060053E1082084E555\r
+S31500016A2000608515043095E5000053E3E1FFFF1A88\r
+S31500016A3028301BE50840A0E1000053E30900001AD5\r
+S31500016A400800A0E1702400EB44209FE5003092E5A8\r
+S31500016A50010053E2000082150000000AF0AD1BE9B7\r
+S31500016A60B6FDFFEBFCFFFFEA0400A0E17AFDFFEBB8\r
+S31500016A700010A0E10700A0E168FDFFEB28301BE54F\r
+S31500016A80000053E3F7FFFF1AECFFFFEA63FDFFEB9C\r
+S31500016A90E3FFFFEAF42002000DC0A0E1F0DD2DE9DD\r
+S31500016AA004B04CE210D04DE20250A0E10080A0E11A\r
+S31500016AB00170A0E1FF2002E220619FE5003096E52A\r
+S31500016AC0013083E2003086E5B20000EB000050E3BE\r
+S31500016AD00040A0E10700000A003096E5010053E2FC\r
+S31500016AE0000086150100000A0400A0E1F0AD1BE9D3\r
+S31500016AF092FDFFEBFBFFFFEA023005E2E0009FE5B6\r
+S31500016B00000053E30730A0010030A013006090E5B8\r
+S31500016B100720A0110020A00334300BE5011005E287\r
+S31500016B2034304BE22C400BE530200BE528100BE509\r
+S31500016B30443086E52C301BE50140A0E3000053E319\r
+S31500016B401B00001A047088E204A0A0E10080A0E105\r
+S31500016B50002098E50050A0E378A082E5003098E592\r
+S31500016B607C5083E571F7FFEB0700A0E10610A0E179\r
+S31500016B702AFDFFEB64309FE5000093E56FFDFFEB17\r
+S31500016B807C3096E5040053E3040000BA050053E3A4\r
+S31500016B900540A0D1010000DA060053E30D00000A0A\r
+S31500016BA0000054E30200000A2C301BE5000053E309\r
+S31500016BB0E6FFFF0A24209FE5003092E5010053E23B\r
+S31500016BC0000082150100000A2C001BE5F0AD1BE94F\r
+S31500016BD05AFDFFEBFBFFFFEAB9F8FFEBEFFFFFEA18\r
+S31500016BE0F42002000C8A02000DC0A0E104D04DE29F\r
+S31500016BF0F0DD2DE908B04CE214D04DE20260A0E1CF\r
+S31500016C0000A0A0E104308BE50170A0E1FF2002E2C3\r
+S31500016C1078419FE5003094E5013083E2003084E558\r
+S31500016C205C0000EB000050E30050A0E10700000A01\r
+S31500016C30003094E5010053E2000084150100000ACA\r
+S31500016C400500A0E1F0AD1BE93CFDFFEBFBFFFFEA10\r
+S31500016C503C819FE5023006E2000053E3004098E5DF\r
+S31500016C600730A0010030A0130720A0110020A003C7\r
+S31500016C7034300BE5011006E234304BE230200BE5EF\r
+S31500016C8028100BE52C000BE5443084E5002098E53F\r
+S31500016C900360A0E3786082E5001098E50030A0E18A\r
+S31500016CA07C0081E5000098E506009BE94C0080E246\r
+S31500016CB000508DE5F01400EB7C3094E5000053E3C1\r
+S31500016CC00050A0130150A003000055E32000000A64\r
+S31500016CD02C301BE5000053E31D00001A04708AE204\r
+S31500016CE006A0A0E10860A0E1003096E578A083E562\r
+S31500016CF0002096E50030A0E37C3082E50BF7FFEB40\r
+S31500016D000700A0E10410A0E1C4FCFFEB7C309FE585\r
+S31500016D10000093E509FDFFEB7C3094E5033043E287\r
+S31500016D20030053E303F19F97040000EA3C6D010061\r
+S31500016D303C6D01003C6D0100886D01000050A0E32F\r
+S31500016D40000055E30200000A2C301BE5000053E366\r
+S31500016D50E4FFFF0A38309FE5000093E54C0080E22E\r
+S31500016D602B1500EB24209FE5003092E5010053E24C\r
+S31500016D70000082150100000A2C001BE5B0FFFFEAA6\r
+S31500016D80EEFCFFEBFBFFFFEA4DF8FFEBEBFFFFEA43\r
+S31500016D90F42002000C8A02000DC0A0E110D82DE9F2\r
+S31500016DA004B04CE2FFE002E201C0A0E178109FE5E9\r
+S31500016DB0003091E5013083E2003081E5020012E303\r
+S31500016DC00040A0E31000000A003090E50C0013E13A\r
+S31500016DD00340A011000054E30200000A01001EE373\r
+S31500016DE00030A013003080153C209FE5003092E56D\r
+S31500016DF0010053E2000082150100000A0400A0E12F\r
+S31500016E0010A81BE9CDFCFFEBFBFFFFEA00005CE3EA\r
+S31500016E10EFFFFF0A002090E50C3002E003005CE181\r
+S31500016E200240A0010040A013E9FFFFEAF42002009E\r
+S31500016E3004E02DE504E09DE4882300EA04E02DE565\r
+S31500016E4004E09DE4852300EA04E02DE504E09DE4E9\r
+S31500016E50882300EA04E02DE504E09DE4852300EAA9\r
+S31500016E600DC0A0E100D82DE904B04CE204D04DE2FA\r
+S31500016E7010104BE2B82300EB000050E310001B1585\r
+S31500016E8000A81BE90DC0A0E100D82DE904B04CE231\r
+S31500016E9004D04DE20230A0E10120A0E110104BE246\r
+S31500016EA0042400EB000050E310001B1500A81BE9A9\r
+S31500016EB00DC0A0E100D82DE904B04CE204D04DE2AA\r
+S31500016EC010104BE2502400EB000050E310001B159C\r
+S31500016ED000A81BE904E02DE504E09DE4722400EA24\r
+S31500016EE004E02DE504E09DE4BC2400EA04E02DE580\r
+S31500016EF004E09DE4192500EA0DC0A0E100D82DE9C2\r
+S31500016F0004B04CE204D04DE210104BE2472500EBF1\r
+S31500016F10000050E310001B1500A81BE90020A0E3A8\r
+S31500016F200130A0E30C3080E5042080E5082080E5EF\r
+S31500016F300020C0E50EF0A0E10020A0E30130A0E3AF\r
+S31500016F400C3080E5042080E5082080E50020C0E5BE\r
+S31500016F500EF0A0E10030A0E3103080E50C1080E5D2\r
+S31500016F60083080E50030C0E5043080E50EF0A0E190\r
+S31500016F700030A0E3103080E50C1080E5083080E594\r
+S31500016F800030C0E5043080E50EF0A0E104E02DE517\r
+S31500016F90080080E204E09DE41B2300EA04E02DE5FD\r
+S31500016FA0080080E204E09DE4172300EA0DC0A0E199\r
+S31500016FB0F0DF2DE978619FE504B04CE20040A0E1E5\r
+S31500016FC001A0A0E3005096E568219FE5003092E517\r
+S31500016FD00A3083E0003082E50C3090E5000053E38F\r
+S31500016FE01C208512103092150A308310103082153C\r
+S31500016FF00C309015020053E34900000A0030D4E535\r
+S31500017000000053E33A00000A0680A0E1087084E21A\r
+S315000170100A90A0E1003098E50060A0E3789083E54E\r
+S31500017020002098E57C6082E540F6FFEB0510A0E1C3\r
+S315000170300700A0E1F9FBFFEB0C3094E50510A0E198\r
+S31500017040010053E33200000AE8309FE5000093E5B2\r
+S315000170503AFCFFEB7C3095E5040053E3040000BAEB\r
+S31500017060050053E306A0A0D1010000DA060053E3B0\r
+S315000170702500000A0030D4E5000053E31C00000A95\r
+S3150001708000005AE3E2FFFF1A0C3094E5000053E3D7\r
+S315000170901C208512103092150130431210308215D2\r
+S315000170A00C309415010053E30D00000A020053E36E\r
+S315000170B00800000A7C209FE5003092E5010053E2BA\r
+S315000170C0000082150100000A0A00A0E1F0AF1BE9E9\r
+S315000170D01AFCFFEBFBFFFFEA1C0085E2B7FCFFEBA6\r
+S315000170E0F3FFFFEA1C0085E2ADFCFFEB0C3094E5F3\r
+S315000170F0EDFFFFEA00005AE30130A01304508415A6\r
+S315000171000030C415EAFFFF1ADEFFFFEA6CF7FFEB5A\r
+S31500017110D7FFFFEA040094E51C0080E298FCFFEB30\r
+S31500017120C8FFFFEA101094E51C0085E29FFCFFEB07\r
+S31500017130B1FFFFEA0C8A0200F42002000DC0A0E1B3\r
+S3150001714010D82DE904B04CE20140A0E300C0A0E153\r
+S3150001715088309FE5002093E5042082E0002083E546\r
+S315000171600030D0E5000053E31A00001A70309FE5A5\r
+S315000171700C1090E5002093E5000051E31CE082E24B\r
+S315000171800040CCE504208CE510309E151C0082E2FF\r
+S315000171900430831010308E150C109C15020051E33B\r
+S315000171A00900000A34209FE5003092E5013053E2E0\r
+S315000171B00300A0E1003082150100000A0400A0E1ED\r
+S315000171C010A81BE9DDFBFFEBFBFFFFEA10109CE5B6\r
+S315000171D076FCFFEBF2FFFFEA0040A0E3F0FFFFEAD7\r
+S315000171E0F42002000C8A02000DC0A0E1F0D82DE9BE\r
+S315000171F004B04CE20040A0E1EC309FE5002093E5AD\r
+S31500017200012082E2002083E5083090E5087080E2E3\r
+S31500017210000053E30060A0130160A003000056E3E1\r
+S315000172202000000A0C3094E5000053E30500000A33\r
+S31500017230042094E51C2082E2103092E5013043E2FD\r
+S31500017240103082E50C3094E5010053E31000000A8A\r
+S31500017250020053E30A00000A0030A0E3043084E58B\r
+S315000172600030C4E580209FE5003092E5010053E23D\r
+S31500017270000082150000000AF0A81BE9AFFBFFEB36\r
+S31500017280FCFFFFEA040094E51C0080E24BFCFFEBE7\r
+S31500017290F0FFFFEA040094E51C0080E240FCFFEBEE\r
+S315000172A00C3094E5E9FFFFEA0700A0E16AFBFFEB7A\r
+S315000172B00C3094E50050A0E1010053E30500000AFB\r
+S315000172C00730A0E3786085E57C3085E50500A0E11F\r
+S315000172D0B4F5FFEBD2FFFFEA041094E51C0080E24F\r
+S315000172E00720A0E12BFCFFEBF4FFFFEAF4200200EC\r
+S315000172F00DC0A0E130D82DE904B04CE20040A0E178\r
+S3150001730054309FE5002093E5012082E2002083E5C9\r
+S31500017310083090E5085080E2000053E30700001AA8\r
+S3150001732034209FE5003092E5010053E2000082150A\r
+S315000173300000000A30A81BE980FBFFEBFCFFFFEA17\r
+S315000173400500A0E144FBFFEBBCF6FFEB083094E53A\r
+S31500017350000053E3F9FFFF1AF0FFFFEAF4200200F1\r
+S315000173600DC0A0E100D82DE904B04CE22C209FE528\r
+S31500017370003092E5013083E2003082E5101080E5AD\r
+S31500017380003092E5013053E20300A0E1003082159E\r
+S315000173900000000A00A81BE968FBFFEBFCFFFFEAFF\r
+S315000173A0F42002000DC0A0E100D82DE904B04CE2A2\r
+S315000173B02C209FE5003092E5013083E2003082E522\r
+S315000173C00C1080E5003092E5013053E20300A0E1A4\r
+S315000173D0003082150000000A00A81BE957FBFFEBED\r
+S315000173E0FCFFFFEAF42002000030A0E30A0080E877\r
+S315000173F00EF0A0E10030A0E30A0080E80EF0A0E163\r
+S315000174000030A0E3003080E5043080E50EF0A0E115\r
+S315000174100030A0E3003080E5043080E50EF0A0E105\r
+S3150001742004E02DE5040080E204E09DE4F62100EA93\r
+S3150001743004E02DE5040080E204E09DE4F22100EA87\r
+S315000174400DC0A0E1F0DF2DE99C409FE504B04CE2C0\r
+S315000174500060A0E10180A0E101A0A0E3007094E535\r
+S3150001746088509FE5003095E50A3083E0003085E5D8\r
+S315000174700100A0E15BFFFFEB002094E50090A0E393\r
+S3150001748078A082E5003094E5046086E27C9083E58D\r
+S3150001749026F5FFEB0600A0E10710A0E1DFFAFFEBFE\r
+S315000174A0000095E5010040E224FBFFEB7C3097E507\r
+S315000174B0040053E3040000BA050053E309A0A0D178\r
+S315000174C0010000DA060053E30500000A0800A0E106\r
+S315000174D0B5FEFFEB000050E30A00A011F0AF1B1947\r
+S315000174E0F9FFFFEA76F6FFEBF7FFFFEA0C8A0200E7\r
+S315000174F0F42002000DC0A0E130D82DE904B04CE221\r
+S315000175005C509FE5003095E5013083E2003085E56A\r
+S31500017510043090E5040080E2000053E30040A0132C\r
+S315000175200140A003000054E30700000A003095E57E\r
+S31500017530013053E20300A0E1003085150000000A86\r
+S3150001754030A81BE9FDFAFFEBFCFFFFEAC2FAFFEBED\r
+S315000175500730A0E37C3080E5784080E511F5FFEB4C\r
+S31500017560F1FFFFEAF42002000DC0A0E1F0D82DE9F9\r
+S3150001757004B04CE20040A0E16C309FE5002093E5A9\r
+S31500017580012082E2002083E5043090E5045080E288\r
+S31500017590000053E30030A0130130A003000053E3C1\r
+S315000175A00900001A0370A0E10760A0E30500A0E14D\r
+S315000175B0A9FAFFEB7C6080E5787080E5F9F4FFEBD2\r
+S315000175C0043094E5000053E3F7FFFF1A18209FE506\r
+S315000175D0003092E5010053E2000082150000000A26\r
+S315000175E0F0A81BE9D5FAFFEBFCFFFFEAF420020045\r
+S315000175F00DC0A0E1F0DF2DE9E8809FE504B04CE283\r
+S315000176000CD04DE20350A0E10240A0E10130A0E31D\r
+S315000176102C000BE50160A0E130300BE5007098E528\r
+S31500017620C4909FE5003099E5013083E2003089E599\r
+S315000176300100A0E1EBFEFFEBBCF4FFEB002098E5B7\r
+S315000176400330A0E3783082E5001098E500A0A0E3BE\r
+S315000176507CA081E5000098E50A30A0E10520A0E1C3\r
+S315000176600410A0E14C0080E200A08DE5821200EB3F\r
+S315000176707C3097E50A0053E11500000A000099E500\r
+S31500017680010040E2ADFAFFEB000098E54C0080E214\r
+S31500017690DF1200EB7C1097E5030051E3040000BA0A\r
+S315000176A0050051E330A00BD5010000DA060051E3D5\r
+S315000176B00500000A0600A0E13BFEFFEB000050E3D7\r
+S315000176C030001B15F0AF1B19F9FFFFEAFCF5FFEBC4\r
+S315000176D0F7FFFFEA2C301BE50710A0E1040083E267\r
+S315000176E04EFAFFEBE4FFFFEA0C8A0200F4200200E7\r
+S315000176F00DC0A0E100D82DE90130A0E104B04CE2B3\r
+S31500017700070050E300F19F97090000EA2C7701007A\r
+S315000177103C7701004877010054770100607701004A\r
+S31500017720707701007C770100887701000100A0E3F2\r
+S3150001773000A81BE90000A0E300A81BE9000091E5F1\r
+S31500017740200000EB00A81BE9000091E54E0000EBCC\r
+S3150001775000A81BE9070091E8630000EB00A81BE9FC\r
+S31500017760041091E5000093E5B90000EB00A81BE9C0\r
+S31500017770070091E80D0100EB00A81BE9070091E85D\r
+S31500017780390100EB00A81BE9070091E8600100EB55\r
+S3150001779000A81BE904309FE53C3080E50EF0A0E12E\r
+S315000177A0F07601000030A0E12004A0E10324A0E16D\r
+S315000177B0FF0C00E2230C80E1FF2802E2020080E1D7\r
+S315000177C0030C80E10EF0A0E11F30A0E3003080E55C\r
+S315000177D00100A0E30EF0A0E10020A0E30DC0A0E1AE\r
+S315000177E0010070E30200501110D82DE90030A0E12C\r
+S315000177F004B04CE20140A0E104208105002081058E\r
+S3150001780010A81B09F804D0E1003081E50008A0E1C9\r
+S315000178102008A0E1E2FFFFEB040084E510A81BE9C4\r
+S315000178200DC0A0E100D82DE904B04CE2040090E5BA\r
+S31500017830DBFFFFEB4C309FE50008A0E1003093E54C\r
+S315000178404028A0E1000053E39C309315000053E269\r
+S3150001785000A81B090238A0E128C09FE52318A0E172\r
+S31500017860B834D0E10020A0E3010053E100A81B09D0\r
+S3150001787000309CE5030050E19C209015000052E287\r
+S3150001788000A81B09F5FFFFEAE82002000DC0A0E1F0\r
+S3150001789000D82DE914309FE50010A0E104B04CE2B8\r
+S315000178A0000093E5CBFFFFEB0100A0E300A81BE975\r
+S315000178B00C8A02000DC0A0E100D82DE904B04CE20B\r
+S315000178C0D6FFFFEB000050E30030A0E1B834D01141\r
+S315000178D00300A0E100A81BE908309FE5002093E51D\r
+S315000178E0B804D2E10EF0A0E10C8A02000DC0A0E1BD\r
+S315000178F0000050E330D82DE90040A0E104B04CE28D\r
+S315000179000100A0E10250A0E10800000A48309FE50D\r
+S31500017910003093E5000053E39C0093150300A0019A\r
+S315000179200510A0E1ABFFFFEB0100A0E330A81BE9C6\r
+S31500017930BAFFFFEB000050E330A81B0918309FE5A2\r
+S31500017940002093E5020050E19C0090150400A0017F\r
+S31500017950000050E3F1FFFF1A30A81BE9E8200200FE\r
+S315000179600130D1E4000053E30130C0E401004002DC\r
+S315000179700EF0A001F9FFFFEA0DC0A0E1F0DF2DE94D\r
+S31500017980000051E30140A0E12B90A0E3004061B269\r
+S31500017990029089B2000054E304B04CE210D04DE2EB\r
+S315000179A00050A0E33030A0030060A0E10280A0E116\r
+S315000179B088A09FE50150850238304B050D00000A6D\r
+S315000179C028704BE20400A0E10810A0E1D71600EBF5\r
+S315000179D00030DAE70810A0E10400A0E1103047E525\r
+S315000179E0A61600EB000050E30040A0E1017087E21B\r
+S315000179F0015085E2F2FFFF1A2D0059E328204B02C0\r
+S31500017A00053082000150451210904305000055E3F0\r
+S31500017A10060000BA28304BE2032085E0103052E51B\r
+S31500017A20015055E20130C6E4012042E2FAFFFF5A55\r
+S31500017A300030A0E30030C6E50600A0E1F0AF1BE987\r
+S31500017A407011020004E02DE50A20A0E304E09DE4A4\r
+S31500017A50C8FFFFEA0DC0A0E170D82DE904B04CE2E1\r
+S31500017A600150A0E16DFFFFEB000050E30040A0E1F3\r
+S31500017A7070A81B090130A0E3083085E5381090E5B0\r
+S31500017A80F8609FE5040011E30600A0E13700001A43\r
+S31500017A900430C1E3100053E303F19F972F0000EA7E\r
+S31500017AA0E47A0100447B01004C7B01004C7B010020\r
+S31500017AB0607B0100607B0100607B0100607B01004F\r
+S31500017AC0547B0100607B0100607B0100607B01004B\r
+S31500017AD0607B0100607B0100607B0100607B01002F\r
+S31500017AE0687B010098309FE5002093E5040052E190\r
+S31500017AF090109F050300000A040011E388109F15EA\r
+S31500017B0088109F050100401294FFFFEB80109FE54E\r
+S31500017B1092FFFFEB343094E5000053E330109415E7\r
+S31500017B2024109405C6FFFFEB0C6085E5982094E5CB\r
+S31500017B300030A0E30100A0E3143085E5102085E5BF\r
+S31500017B4070A81BE94C109FE5EEFFFFEA48109FE580\r
+S31500017B50ECFFFFEA44109FE50600A0E1E9FFFFEA1A\r
+S31500017B603C109FE5E7FFFFEA38109FE5F9FFFFEAC2\r
+S31500017B7034109FE579FFFFEB381094E5C3FFFFEA68\r
+S31500017B809C8A02000C8A02008C120200C8080200BC\r
+S31500017B902812020030120200401202004C120200AA\r
+S31500017BA05C120200681202007812020080120200C2\r
+S31500017BB00DC0A0E130D82DE904B04CE20240A0E1AD\r
+S31500017BC016FFFFEB000050E330A81B0994309FE538\r
+S31500017BD0002093E5020050E10000A00330A81B0934\r
+S31500017BE0183090E5000053E30C0090050300A01146\r
+S31500017BF0000050E330A81B0900C0A0E30C3190E758\r
+S31500017C000C3184E701C08CE20A005CE3FAFFFFDA7B\r
+S31500017C102C3090E540E084E22C3084E5302090E57C\r
+S31500017C200050A0E3302084E5341090E517C0A0E3AE\r
+S31500017C30341084E5383090E5383084E53C2090E511\r
+S31500017C403C2084E5403090E5A43084E501C05CE247\r
+S31500017C5004508EE4FCFFFF5A0030A0E30100A0E3CC\r
+S31500017C60A03084E530A81BE90C8A02000DC0A0E112\r
+S31500017C7010D82DE904B04CE20240A0E1E7FEFFEB8B\r
+S31500017C80000050E31F00000A80309FE5002093E5C5\r
+S31500017C90020050E10010A0031800000A183090E518\r
+S31500017CA0000053E30C0090050300A011000050E30F\r
+S31500017CB00020A0131300000A023194E7023180E785\r
+S31500017CC0012082E20A0052E3FAFFFFDA2C2094E552\r
+S31500017CD00110A0E32C2080E5303094E5303080E5BA\r
+S31500017CE0342094E5342080E5383094E5383080E559\r
+S31500017CF03C2094E53C2080E5A43094E5403080E5C5\r
+S31500017D000100A0E110A81BE90010A0E1FBFFFFEABA\r
+S31500017D100C8A02000DC0A0E110D82DE904B04CE296\r
+S31500017D200140A0E1BDFEFFEB000050E310A81B09D6\r
+S31500017D3058309FE5002093E5020050E10000A013B2\r
+S31500017D4010A81B19000054E30500000A40209FE516\r
+S31500017D50003092E5013083E2003082E50100A0E3C4\r
+S31500017D6010A81BE928209FE5003092E5000053E3A7\r
+S31500017D70F9FFFF0A003092E5010053E300309285D6\r
+S31500017D80004082950130438200308285F2FFFFEA8E\r
+S31500017D900C8A0200F42002000DC0A0E110D82DE9E2\r
+S31500017DA02C309FE50010A0E104B04CE2000093E501\r
+S31500017DB020209FE5003092E5013083E2003082E524\r
+S31500017DC0F31100EB0040A0E1272200EB0400A0E143\r
+S31500017DD010A81BE9FC200200F42002000020A0E309\r
+S31500017DE00DC0A0E1020050E100D82DE90010A0E18C\r
+S31500017DF004B04CE200A81B0908309FE5000093E59A\r
+S31500017E00D42100EB00A81BE9FC2002000DC0A0E173\r
+S31500017E1030D82DE9910004E004B04CE20400A0E161\r
+S31500017E20DCFFFFEB000050E30050A0E10420A0E1DD\r
+S31500017E300010A0E39BEEFF1B0500A0E130A81BE9A3\r
+S31500017E400DC0A0E170D82DE9000050E304B04CE26A\r
+S31500017E5004D04DE20050A0E10140A0E11B00000A60\r
+S31500017E60002054E21C304BE20010A0E10200001A8F\r
+S31500017E70D9FFFFEB0400A0E170A81BE958C09FE5FC\r
+S31500017E8000009CE5A02100EB0060A0E1000056E3A4\r
+S31500017E900400A0E10100000A0600A0E170A81BE9A8\r
+S31500017EA0BCFFFFEB000050E30060A0E10510A0E17C\r
+S31500017EB0F8FFFF0A1C201BE5040052E10420A02163\r
+S31500017EC048EEFFEB0500A0E1C3FFFFEBF1FFFFEA80\r
+S31500017ED00100A0E1AFFFFFEB70A81BE9FC20020047\r
+S31500017EE00DC0A0E110D82DE92C20A0E304B04CE28E\r
+S31500017EF02CD04DE20010A0E30040A0E169EEFFEBBB\r
+S31500017F000020A0E30030E0E320204BE58C209FE534\r
+S31500017F1014304BE53C300BE538300BE534300BE5DE\r
+S31500017F2030300BE52C300BE528300BE524300BE522\r
+S31500017F301C300BE518300BE5000092E560209FE54B\r
+S31500017F40003092E5013083E2003082E53C204BE2CD\r
+S31500017F505E10A0E3131400EBC32100EB38301BE5E0\r
+S31500017F600400A0E1000053E3003084C534301BE572\r
+S31500017F70000053E3043084C530301BE5000053E3B1\r
+S31500017F801C3084C52C301BE5000053E3203084C52A\r
+S31500017F9024301BE5000053E3283084C510A81BE9F3\r
+S31500017FA0FC200200F42002000DC0A0E170D82DE9EA\r
+S31500017FB050609FE550309FE5060051E101005003F6\r
+S31500017FC00050A0E10140A0E10F2963E20310A0E106\r
+S31500017FD004B04CE234009FE50030A0E30500000A3E\r
+S31500017FE0060054E10000550320009FE570A81B1907\r
+S31500017FF070681BE9B12100EA14C09FE50FE0A0E11A\r
+S315000180000CF0A0E1F5FFFFEA98B7000068B20200A4\r
+S31500018010D88A0200A006020004E02DE508109FE5BB\r
+S315000180200100A0E304E09DE4DEFFFFEA98B700004B\r
+S3150001803004E02DE508109FE50000A0E304E09DE4BF\r
+S31500018040D8FFFFEA98B700000DC0A0E100D82DE9DE\r
+S315000180500600A0E304B04CE2C02100EBFEFFFFEAFC\r
+S315000180600DC0A0E170D82DE960609FE504B04CE237\r
+S31500018070060051E1010050030CD04DE20050A0E191\r
+S315000180800140A0E148009FE548209FE50A10A0E3D2\r
+S315000180900030A0E30500000A060054E10000550384\r
+S315000180A02C009FE570A81B1970681BE9E9F1FFEA2E\r
+S315000180B024C09FE524E09FE500C08DE502CAA0E348\r
+S315000180C004E08DE508C08DE556F1FFEBF1FFFFEA0F\r
+S315000180D020CB0000ECAE0200B8D1010094120200E0\r
+S315000180E0EC8E020004E02DE508109FE50100A0E3F7\r
+S315000180F004E09DE4D9FFFFEA20CB000004E02DE572\r
+S3150001810008109FE50000A0E304E09DE4D3FFFFEA29\r
+S3150001811020CB00000DC0A0E10E002DE900D82DE90D\r
+S3150001812010B04CE20211E0E304209BE508308BE23B\r
+S31500018130870300EB00A81BE90DC0A0E1F0D82DE9EB\r
+S31500018140E4709FE504B04CE210D04DE2070051E126\r
+S31500018150010050030060A0E10150A0E12200000AE5\r
+S31500018160070055E101005603C0209F05C0309F0559\r
+S3150001817008208305070055E100005603F0A81B19E6\r
+S31500018180A8409FE5043094E5000053E30600001A79\r
+S3150001819098409FE52C0084E27FFBFFEB0C4084E2D4\r
+S315000181A00400A0E1F0681BE9952100EA2C5084E265\r
+S315000181B00500A0E17CFBFFEB000050E3F3FFFF0AA3\r
+S315000181C0043094E5000053E30200001A0500A0E123\r
+S315000181D004FCFFEBEDFFFFEA0400A0E17B0200EBEC\r
+S315000181E00030A0E3043084E5F7FFFFEA0020A0E3B6\r
+S315000181F00230A0E10110A0E338009FE53A0000EB50\r
+S315000182000040A0E30010A0E107C0E0E31C009FE5E9\r
+S315000182100430A0E10120A0E310108DE808408DE5AF\r
+S315000182200C408DE55A0000EBCCFFFFEA22CB0000A3\r
+S315000182308CAF0200042102001C11020004E02DE5AE\r
+S3150001824008109FE50100A0E304E09DE4B9FFFFEA01\r
+S3150001825022CB000004E02DE508109FE50000A0E315\r
+S3150001826004E09DE4B3FFFFEA22CB00000DC0A0E1CC\r
+S3150001827070D82DE938609FE50050A0E1060051E174\r
+S315000182800100500304B04CE20140A0E124009FE547\r
+S315000182900500000A060054E10000550314009FE59D\r
+S315000182A070A81B1970681BE93BFBFFEA21FBFFEB7A\r
+S315000182B0F7FFFFEA20CB0000D0AF020004E02DE576\r
+S315000182C008109FE50100A0E304E09DE4E6FFFFEA54\r
+S315000182D020CB000004E02DE508109FE50000A0E397\r
+S315000182E004E09DE4E0FFFFEA20CB00000DC0A0E121\r
+S315000182F000D82DE904B04CE20C104BE20030A0E3AB\r
+S3150001830004D04DE2043021E511E8FFEB10001BE536\r
+S3150001831000A81BE90DC0A0E1F0DF2DE904B04CE295\r
+S3150001832014D04DE20040A0E110009BE50C909BE5C6\r
+S315000183302C000BE500C0A0E30C0084E20CC084E530\r
+S3150001834010C080E504C080E508C080E50CC080E56A\r
+S315000183500180A0E102A0A0E10910A0E12C201BE50B\r
+S315000183600350A0E1C0009BE9BB0200EB2C0084E2B4\r
+S31500018370F0FAFFEB2CC01BE50400A0E10810A0E118\r
+S315000183800A20A0E10530A0E1C0128BE9F06F1BE9DC\r
+S315000183901F0000EA0DC0A0E1F0DF2DE904B04CE2B8\r
+S315000183A014D04DE20040A0E110009BE50C909BE546\r
+S315000183B02C000BE500C0A0E30C0084E20CC084E5B0\r
+S315000183C010C080E504C080E508C080E50CC080E5EA\r
+S315000183D00180A0E102A0A0E10910A0E12C201BE58B\r
+S315000183E00350A0E1C0009BE99B0200EB2C0084E254\r
+S315000183F0D0FAFFEB2CC01BE50400A0E10810A0E1B8\r
+S315000184000A20A0E10530A0E1C0128BE9F06F1BE95B\r
+S31500018410FFFFFFEA04E02DE502C0A0E1010052E3FF\r
+S315000184200020A0E3041080E5242080E503E0A0E11C\r
+S3150001843008109DE53D00000A370000CA02005CE114\r
+S315000184402430D005023083030200000A1630A0E36F\r
+S31500018450003080E504F09DE42430C0E52420D0E519\r
+S31500018460040012E37F3002120320A0112430C0154C\r
+S31500018470020012E3823CE011A33CE0112430C01556\r
+S315000184800320A01104309DE50920C2E3000053E357\r
+S315000184900830A0130030A003032082E100005EE350\r
+S315000184A0012082130030A0E3040071E3283080E547\r
+S315000184B0003080E52420C0E51500000A0F0000CA3F\r
+S315000184C0080071E3E0FFFF1A6030C2E32430C0E523\r
+S315000184D02430D0E5200013E304F09D040C2080E253\r
+S315000184E0043092E5000053E3083092150030E003B2\r
+S315000184F0010073E304F09D140C30A0E3D3FFFFEAFF\r
+S31500018500020071E3D0FFFF1A203082E34030C3E35B\r
+S31500018510EDFFFFEA603082E3EBFFFFEA02005CE376\r
+S31500018520C9FFFF1A2430D0E5063083E3C9FFFFEA0D\r
+S315000185302430D0E5043083E3C6FFFFEA0DC0A0E195\r
+S31500018540F0DD2DE90040A0E30C6080E210D04DE2A1\r
+S3150001855004B04CE20070A0E10280A0E101A0A0E11C\r
+S315000185600C4080E50210A0E1044086E50320A0E16D\r
+S31500018570084086E50C4086E5104086E50600A0E148\r
+S315000185800350A0E1340200EB2C0087E269FAFFEB0D\r
+S315000185900430A0E101C0E0E30410A0E10700A0E17E\r
+S315000185A00A20A0E104C08DE50C508DE500408DE563\r
+S315000185B008808DE596FFFFEB003097E5040053E157\r
+S315000185C0F0AD1B1904005AE10C3096050830830002\r
+S315000185D00C308605F0AD1B0901005AE31630A013D5\r
+S315000185E000308715F0AD1BE90DC0A0E1F0DD2DE9E6\r
+S315000185F00040A0E30C6080E210D04DE204B04CE2F2\r
+S315000186000070A0E10280A0E101A0A0E10C4080E59C\r
+S315000186100210A0E1044086E50320A0E1084086E5BA\r
+S315000186200C4086E5104086E50600A0E10350A0E176\r
+S31500018630090200EB2C0087E23EFAFFEB0430A0E1D1\r
+S3150001864001C0E0E30410A0E10700A0E10A20A0E1D7\r
+S3150001865004C08DE50C508DE500408DE508808DE563\r
+S315000186606BFFFFEB003097E5040053E1F0AD1B19FA\r
+S3150001867004005AE10C309605083083000C3086055B\r
+S31500018680F0AD1B0901005AE31630A013003087151F\r
+S31500018690F0AD1BE90DC0A0E170D82DE92C6080E298\r
+S315000186A004B04CE208D04DE20040A0E10600A0E192\r
+S315000186B03DFAFFEB000050E30900A00370A81B0977\r
+S315000186C02430D4E5020013E34800000A205013E2E7\r
+S315000186D02B00001A2530D4E5010013E32020840283\r
+S315000186E00130A00320300B051C200B052100001AC8\r
+S315000186F0040094E51C101BE520204BE25DE7FFEB2F\r
+S315000187002430D4E50050A0E1200013E31200000A52\r
+S315000187100C3084E20C2093E520101BE5012082E059\r
+S315000187200C2083E50600A0E1AEFAFFEB000055E35D\r
+S315000187300700001A20301BE5000053E32430D4055E\r
+S315000187402430D415013083030130C3130B50A00329\r
+S315000187502430C4E50500A0E170A81BE92530D4E565\r
+S3150001876020201BE50130C3E3000052E301308313EF\r
+S315000187702530C4E5EAFFFFEA0600A0E199FAFFEB1E\r
+S31500018780F3FFFFEA0400A0E1100100EB2430D4E579\r
+S31500018790000050E3833CE0E1A33CE0E10050A0E1AE\r
+S315000187A02430C4E5F3FFFF1A0400A0E18D1200EBAB\r
+S315000187B0000050E30050A0E1EEFFFF1A0C2084E216\r
+S315000187C0043092E5000053E3081092150010E0030F\r
+S315000187D00C2092E5013083E0035062E0000055E38E\r
+S315000187E01C200BE520500BE5C0FFFF1AE1FFFFEA55\r
+S315000187F00600A0E17BFAFFEB1600A0E370A81BE9D7\r
+S315000188000DC0A0E1F0DD2DE90350A0E12CA080E22E\r
+S315000188100030A0E304B04CE20040A0E1003085E561\r
+S315000188200A00A0E10180A0E10260A0E1DEF9FFEB10\r
+S31500018830000050E30900A003F0AD1B092420D4E594\r
+S31500018840020012E35000000A2232A0E1013003E2E5\r
+S31500018850000056E30030A00301300312000053E389\r
+S315000188600900000A0830D4E5016046E20130C8E497\r
+S31500018870002095E5012082E2002085E52430D4E53B\r
+S315000188801030C3E32430C4E50320A0E1200012E345\r
+S315000188902E00000A800012E32300000A0C7084E215\r
+S315000188A00C2087E20C0092E8033042E0101097E5B5\r
+S315000188B0030056E10360A021000056E30700001AF9\r
+S315000188C0002095E5283094E50A00A0E1023083E016\r
+S315000188D0283084E543FAFFEB0000A0E3F0AD1BE985\r
+S315000188E00620A0E10800A0E1BEEBFFEB043097E50E\r
+S315000188F0041097E5000053E308209715103097E51B\r
+S315000189000020E003063083E0022081E0020053E10B\r
+S31500018910103087E50C10870510108705003095E5A6\r
+S31500018920063083E0003085E5E4FFFFEA0400A0E1BC\r
+S31500018930A60000EB000050E30070A0E1D6FFFF0A9D\r
+S315000189400A00A0E127FAFFEB0700A0E1F0AD1BE961\r
+S315000189502530D4E5013003E2000056E30030A003E0\r
+S3150001896001300312000053E3D4FFFF0A2030D4E59F\r
+S315000189700120A0E30030C8E5002085E52530D4E5D7\r
+S315000189800130C3E32530C4E5CCFFFFEA0A00A0E1CC\r
+S3150001899014FAFFEB1600A0E3F0AD1BE90DC0A0E150\r
+S315000189A0F0D82DE92C5080E204B04CE20040A0E161\r
+S315000189B00500A0E10160A0E17BF9FFEB000050E3B7\r
+S315000189C00070A0E30900A003F0A81B092430D4E538\r
+S315000189D0020013E33F00000A100013E33300001AFC\r
+S315000189E0200013E32500000A800013E31F00000A9C\r
+S315000189F0000057E31700001A0C1084E20C2081E2F4\r
+S31500018A000C0092E8033042E0102091E5000053E3A8\r
+S31500018A101400000A0030D2E50030C6E5042091E5D5\r
+S31500018A20103091E5000052E3040091E5082091150C\r
+S31500018A300020E003013083E2022080E0020053E1DE\r
+S31500018A40103081E50C00810510008105283094E580\r
+S31500018A50013083E2283084E50500A0E1E1F9FFEB6E\r
+S31500018A600700A0E1F0A81BE90B70A0E3F9FFFFEAFC\r
+S31500018A700400A0E1550000EB0070A0E1DBFFFFEA76\r
+S31500018A802530D4E5010013E3F6FFFF0A2030D4E5D3\r
+S31500018A900030C6E52520D4E5283094E50120C2E35F\r
+S31500018AA0013083E2283084E52520C4E5E9FFFFEAA9\r
+S31500018AB00830D4E50500A0E10030C6E52420D4E560\r
+S31500018AC0283094E51020C2E3013083E2283084E5A2\r
+S31500018AD02420C4E5E0FFFFEA0500A0E1C1F9FFEBB0\r
+S31500018AE01600A0E3F0A81BE90DC0A0E1F0D82DE91E\r
+S31500018AF02C5080E204B04CE20040A0E10500A0E168\r
+S31500018B000170A0E128F9FFEB000050E30060A0E34B\r
+S31500018B100900A003F0A81B092430D4E5020013E3E1\r
+S31500018B202600000A200013E32000001A000056E385\r
+S31500018B301500001A2430D4E5833CE0E1A33CE0E1D2\r
+S31500018B40100013E32430C4E50830D4150500A01144\r
+S31500018B500030C7150B00001A200013E30E00000AAF\r
+S31500018B600C3084E20C1083E2060091E8022041E019\r
+S31500018B70100093E5000052E30030D0150400001AFE\r
+S31500018B800B60A0E30500A0E196F9FFEB0600A0E16A\r
+S31500018B90F0A81BE90030C7E5F9FFFFEA2530D4E567\r
+S31500018BA0010013E3F5FFFF0A2030D4E5F8FFFFEAE1\r
+S31500018BB00400A0E1050000EB0060A0E1DAFFFFEA96\r
+S31500018BC00500A0E187F9FFEB1600A0E3F0A81BE979\r
+S31500018BD00DC0A0E170D82DE904B04CE204D04DE2FD\r
+S31500018BE00050A0E32430D0E50040A0E1800013E36B\r
+S31500018BF00500A0E170A81B19040013E30C6084E2D0\r
+S31500018C001600A0E370A81B090C1086E20A0091E881\r
+S31500018C10033041E018204BE2000053E30500A0E1D8\r
+S31500018C20101096E570A81B09040094E5043022E5AE\r
+S31500018C30FDE5FFEB000050E30050A0E128109FE5A1\r
+S31500018C400020A0E10030A0E10400000A043096E50E\r
+S31500018C500500A0E10C3086E5103086E570A81BE919\r
+S31500018C60040094E54EE6FFEBF7FFFFEA0201000080\r
+S31500018C700DC0A0E1F0DF2DE90090A0E304B04CE2C5\r
+S31500018C8010D04DE20060A0E12C0080E2009083E567\r
+S31500018C9003A0A0E134000BE50170A0E10280A0E190\r
+S31500018CA0C1F8FFEB090050E10900A003F0AF1B0971\r
+S31500018CB02430D6E5040013E36300000A800013E3C1\r
+S31500018CC00C508612043095150C308515103085151B\r
+S31500018CD02430D615200013E37F3003E22430C6E5A5\r
+S31500018CE05000000A000058E338900BE53500000AF1\r
+S31500018CF00C5086E2041095E50C3095E5000051E331\r
+S31500018D00082095150020E00330300BE538001BE5FF\r
+S31500018D10021081E00C2095E5003050E20130A013ED\r
+S31500018D20020051E101308303000053E3011062E0C8\r
+S31500018D302F00001A000059E32500001A2430D6E559\r
+S31500018D40010058E10840A0310140A021400013E391\r
+S31500018D500C00000A040059E10920A0E10500002ADF\r
+S31500018D600230D7E70A0053E30200000A012082E23B\r
+S31500018D70040052E1F9FFFF3A040052E10130A01369\r
+S31500018D800140821238300B150710A0E10420A0E142\r
+S31500018D9030001BE593EAFFEB00309AE5048058E0CA\r
+S31500018DA0043083E000308AE50C2095E5047087E005\r
+S31500018DB0042082E00C2085E5283096E5043083E026\r
+S31500018DC0283086E5CAFFFF1A38001BE5000050E38C\r
+S31500018DD00300001A34001BE502F9FFEB0900A0E1CC\r
+S31500018DE0F0AF1BE90600A0E178FFFFEB0090A0E1E0\r
+S31500018DF0F7FFFFEA0600A0E174FFFFEB041095E51B\r
+S31500018E000C3095E5000051E3082095150020E0039C\r
+S31500018E1030300BE5021081E00C2095E50090A0E1D1\r
+S31500018E20011062E0C2FFFFEA28204BE2040096E54A\r
+S31500018E300710A0E1048022E57BE5FFEB2C301BE562\r
+S31500018E400090A0E100308AE5E1FFFFEA34001BE56E\r
+S31500018E50E4F8FFEB1600A0E3F0AF1BE90DC0A0E1BB\r
+S31500018E60000052E370D82DE904B04CE20250A0E1B3\r
+S31500018E700040A0E10160A0E10E00000A003090E58B\r
+S31500018E80000053E30600001A045084E5043094E51B\r
+S31500018E900000A0E3086084E50C3084E5103084E529\r
+S31500018EA070A81BE9040090E5CBFBFFEB0030A0E3C3\r
+S31500018EB0003084E5F3FFFFEA083090E5030051E155\r
+S31500018EC0F1FFFF0A0100A0E1B2FBFFEB000050E356\r
+S31500018ED00050A0E10C00A00370A81B09003094E526\r
+S31500018EE0000053E30200001A0130A0E3280084E8E1\r
+S31500018EF0E5FFFFEA040094E5B7FBFFEBF9FFFFEAA4\r
+S31500018F0010402DE9003092E500C0A0E303005CE1CA\r
+S31500018F1002E0A0E10140A0E1140090E50900002A69\r
+S31500018F200C10D4E7002090E501C08CE20010C2E5E8\r
+S31500018F30003090E500209EE5013083E202005CE10D\r
+S31500018F40003080E5F5FFFF3A00C08EE50000A0E3A2\r
+S31500018F501080BDE80DC0A0E1F0D92DE904B04CE2C6\r
+S31500018F6070D04DE207C0E0E3E4E09FE504C08DE583\r
+S31500018F70E0C09FE50070A0E37C804BE20140A0E1E8\r
+S31500018F800250A0E180000BE50360A0E13C104BE23A\r
+S31500018F900800A0E10730A0E10120A0E33CC00BE5F9\r
+S31500018FA034E00BE580C04BE201EAA0E328C00BE503\r
+S31500018FB024E00BE500708DE538700BE530700BE5AC\r
+S31500018FC02C700BE508708DE50C708DE5F0FCFFEB60\r
+S31500018FD00410A0E10520A0E10630A0E10800A0E10F\r
+S31500018FE0260000EB80301BE50040A0E10070C3E5E0\r
+S31500018FF078301BE550004BE2070053E150504BE23D\r
+S315000190000500001A0500A0E1E3F7FFEB0C0088E27A\r
+S31500019010FB1D00EB0400A0E1F0A91BE9E2F7FFEB61\r
+S31500019020070050E150504B02F5FFFF0A78301BE56F\r
+S315000190300800A0E1070053E10200001A0500A0E1C3\r
+S3150001904068F8FFEBEEFFFFEAE0FEFFEB78700BE559\r
+S31500019050F9FFFFEA24210200A01202000DC0A0E1DF\r
+S315000190600E002DE900D82DE910B04CE20211E0E323\r
+S3150001907004209BE508308BE2000000EB00A81BE909\r
+S315000190800DC0A0E1F0DF2DE904B04CE21DDE4DE29A\r
+S3150001909000C0A0E30280A0E1D8C10BE5B4010BE555\r
+S315000190A0B8110BE5BC310BE5C4C10BE50030D8E5C1\r
+S315000190B00870A0E1004053E20140A013000054E310\r
+S315000190C00800000A250053E3048088E00180480275\r
+S315000190D00400000A0030D8E5004053E20140A01325\r
+S315000190E0000054E3F6FFFF1A075058E0EC03001A9C\r
+S315000190F0C4C11BE5B8E11BE50E005CE10030A0B37D\r
+S315000191000130A0A3000054E3013083D3000053E3F0\r
+S31500019110C501001AC8310BE5010C4BE2C80050E548\r
+S31500019120C0310BE529004BE50110F8E50090E0E3BD\r
+S31500019130CC310BE5DC310BE5FFA001E2018088E2D1\r
+S3150001914020304AE25A0053E303F19F97C80300EA2D\r
+S31500019150BC92010074A0010074A00100DC92010020\r
+S3150001916074A0010074A0010074A0010074A00100A4\r
+S3150001917074A0010074A00100F09201002C9301007B\r
+S3150001918074A00100189301003493010074A001003A\r
+S31500019190B4930100C8930100C8930100C89301006C\r
+S315000191A0C8930100C8930100C8930100C893010048\r
+S315000191B0C8930100C893010074A0010074A00100C6\r
+S315000191C074A0010074A0010074A0010074A0010044\r
+S315000191D074A0010074A0010074A0010074A0010034\r
+S315000191E0F49301002C9E010074A001002C9E010045\r
+S315000191F074A0010074A0010074A0010074A0010014\r
+S31500019200F89B010074A0010074A00100089C0100F4\r
+S3150001921074A0010074A0010074A0010074A00100F3\r
+S3150001922074A00100A49C010074A0010074A00100B7\r
+S31500019230489D010074A0010074A0010074A0010002\r
+S3150001924074A0010074A0010074A0010074A00100C3\r
+S3150001925074A0010074A0010074A00100009E010029\r
+S31500019260009401002C9E01002C9E01002C9E010001\r
+S31500019270D49E01000094010074A0010074A00100B5\r
+S31500019280E89E010074A00100109F0100149C0100DA\r
+S31500019290BC9F0100F49F010074A0010004A001001D\r
+S315000192A074A00100B09C010074A0010074A001002B\r
+S315000192B068A0010074A0010094A0010029305BE5BB\r
+S315000192C0000053E32030A0030100000A0010D8E596\r
+S315000192D098FFFFEA29304BE5FBFFFFEAC0311BE5AA\r
+S315000192E00010D8E5013083E3C0310BE591FFFFEAB9\r
+S315000192F0BC311BE5BCC11BE5003093E504C08CE223\r
+S31500019300000053E3C8310BE5BCC10BE5EEFFFFAA34\r
+S31500019310003063E2C8310BE5C0E11BE50010D8E57A\r
+S3150001932004E08EE3C0E10BE582FFFFEA2B30A0E308\r
+S31500019330E7FFFFEA0130D8E4FFA003E22A005AE37F\r
+S315000193401000000A30304AE2090053E30040A0E36E\r
+S315000193500700008A0110D8E4042184E082208AE013\r
+S31500019360FFA001E230304AE2090053E3304042E215\r
+S31500019370F7FFFF9A0030E0E3030054E10490A0A157\r
+S315000193800390A0B16DFFFFEABC311BE5BC011BE5F3\r
+S31500019390004093E50010D8E50030E0E3040080E2E8\r
+S315000193A0030054E10490A0A10390A0B1BC010BE518\r
+S315000193B060FFFFEAC0211BE50010D8E5802082E3AB\r
+S315000193C0C0210BE55BFFFFEA0040A0E30110D8E4F2\r
+S315000193D0042184E082208AE0FFA001E230304AE2E3\r
+S315000193E0090053E3304042E2C8410B8553FFFF8A2F\r
+S315000193F0F5FFFFEAC0E11BE510E08EE3C0E10BE5F6\r
+S31500019400C0011BE5200010E3E101000ABC311BE5A8\r
+S31500019410600093E8081083E2BC110BE5000056E3F7\r
+S31500019420D60100BA0120A0E3000059E3C0111BA533\r
+S31500019430CC910BE58010C1A3C0110BA5CCC11BE5D6\r
+S31500019440063095E10030A0E30130A01300005CE393\r
+S3150001945001308313010013E32C704BE29901000ADA\r
+S31500019460010052E3AA01000A9B0100CA000052E36F\r
+S315000194708301000A7C7C9FE50700A0E1270600EB3B\r
+S31500019480D4010BE529305BE5D4C11BE5DCE11BE525\r
+S31500019490000053E30E908CE0019089120200001A3D\r
+S315000194A0C0011BE5020010E302908912CC111BE5F5\r
+S315000194B0C0211BE5010059E10910A0A1842012E297\r
+S315000194C0D0110BE5E0210BE52E00001AC8C11BE502\r
+S315000194D00C2061E0000052E3E4210BE5290000DAEB\r
+S315000194E0100052E30240A0E1610100DAB8E11BE598\r
+S315000194F0C4011BE50E6060E0015046E2100055E331\r
+S315000195001050A023F01B9FE5B4011BE50520A0E147\r
+S31500019510063D4BE280510BE5D4FDFFEB000050E325\r
+S31500019520104044E2C000001A80311BE50F0053E3EE\r
+S31500019530CD00009A100054E3F1FFFFCA01C046E2D4\r
+S3150001954004005CE104C0A021AC1B9FE50C20A0E156\r
+S31500019550B4011BE5613F4BE284C10BE5C3FDFFEBA3\r
+S31500019560000050E3B000001A84311BE5040053E10A\r
+S31500019570AA00003AC4C11BE5E4E11BE529305BE51D\r
+S315000195800EC08CE0C4C10BE5FF0013E32301001AF2\r
+S31500019590C0311BE5020013E30401001AE0011BE5DB\r
+S315000195A0800050E3CC00000ACCC11BE50CA069E0A9\r
+S315000195B000005AE3280000DA10005AE30A40A0E14D\r
+S315000195C0C10000DAB8E11BE5C4011BE5669F4BE269\r
+S315000195D00E6060E0015046E2100055E31050A023F2\r
+S315000195E0181B9FE5B4011BE50520A0E10930A0E1A8\r
+S315000195F098510BE59DFDFFEB000050E3104044E25E\r
+S315000196008900001A98311BE50F0053E39600009A72\r
+S31500019610100054E3F1FFFFCA01C046E204005CE119\r
+S3150001962004C0A021D41A9FE50C20A0E1B4011BE5DA\r
+S31500019630673F4BE29CC10BE58CFDFFEB000050E35D\r
+S315000196407900001A9C311BE5040053E17300003ACE\r
+S31500019650C4311BE50A3083E0C4310BE5C4011BE5C7\r
+S31500019660B8E11BE5D4111BE50EC060E001C04CE278\r
+S3150001967001005CE101C0A0210C20A0E10710A0E1DE\r
+S31500019680B4011BE51A3E4BE2A0C10BE577FDFFEBEA\r
+S31500019690000050E36400001AA0311BE5D4211BE54C\r
+S315000196A0020053E18400003AC4311BE5DC411BE5AD\r
+S315000196B0023083E0000054E3C4310BE5230000DAF5\r
+S315000196C0100054E3780000DAB8C11BE5697F4BE26C\r
+S315000196D00C6063E0015046E2100055E31050A023F0\r
+S315000196E0181A9FE5B4011BE50520A0E10730A0E1AA\r
+S315000196F0A4510BE55DFDFFEB000050E3104044E291\r
+S315000197004900001AA4311BE50F0053E36200009AD9\r
+S31500019710100054E3F1FFFFCA01C046E204005CE118\r
+S3150001972004C0A021D4199FE50C20A0E1B4011BE5DA\r
+S315000197306A3F4BE2A8C10BE54CFDFFEB000050E38D\r
+S315000197403900001AA8311BE5040053E14E00003A26\r
+S31500019750C4211BE5C0111BE5DC311BE5040011E347\r
+S31500019760032082E0C4210BE54FFEFF0AC8C11BE5B9\r
+S31500019770D0E11BE50C706EE0000057E34AFEFFDA0C\r
+S31500019780100057E30740A0E13B0000DAB8011BE5F2\r
+S315000197906BAF4BE2006062E0015046E2100055E318\r
+S315000197A01050A02350199FE5B4011BE50520A0E147\r
+S315000197B00A30A0E1AC510BE52CFDFFEB000050E3B4\r
+S315000197C0104044E21800001AAC311BE50F0053E3C8\r
+S315000197D02500009A100054E3F1FFFFCA01C046E2DA\r
+S315000197E004005CE104C0A0210C199FE50C20A0E156\r
+S315000197F0B4011BE51B3E4BE2B0C10BE51BFDFFEBC4\r
+S31500019800000050E30800001AB0311BE5040053E1E3\r
+S31500019810C4311B2507308320C4310B2522FEFF2AC4\r
+S31500019820C4E11BE503E08EE0C4E10BE5B4C11BE531\r
+S315000198302C508CE20500A0E1DBF5FFEB000050E3C4\r
+S315000198400940A0030300001AC4011BE5000054E30C\r
+S315000198500000E013F0AF1BE9B4111BE50500A0E120\r
+S31500019860004091E55FF6FFEBF6FFFFEAC4011BE559\r
+S31500019870030080E0C4010BE5EBFFFFEAB8111BE52D\r
+S31500019880C4211BE5016062E0D3FFFFEAC4111BE5B9\r
+S31500019890031081E0C4110BE5E3FFFFEAC4211BE5D8\r
+S315000198A0032082E0C4210BE5DFFFFFEAB8E11BE5F7\r
+S315000198B0C4011BE50E6060E096FFFFEAC4C11BE52B\r
+S315000198C003C08CE0C4C10BE5D7FFFFEAB8111BE565\r
+S315000198D0C4211BE5016062E04EFFFFEAC8111BE5EA\r
+S315000198E0D0311BE5012063E0000052E3E8210BE5DE\r
+S315000198F02CFFFFDA100052E30240A0E1270000DA54\r
+S31500019900B8C11BE5C4E11BE519AE4BE20C606EE084\r
+S31500019910015046E2100055E31050A023DC179FE5E5\r
+S31500019920B4011BE50520A0E10A30A0E190510BE549\r
+S31500019930CEFCFFEB000050E3104044E2BAFFFF1AF1\r
+S3150001994090311BE50F0053E3D3FFFF9A100054E358\r
+S31500019950F1FFFFCA01C046E204005CE104C0A02198\r
+S3150001996098179FE50C20A0E1B4011BE5653F4BE28A\r
+S3150001997094C10BE5BDFCFFEB000050E3AAFFFF1A03\r
+S3150001998094311BE5040053E1BFFFFF3AC4211BE5F7\r
+S31500019990E8311BE5032082E0C4210BE501FFFFEA64\r
+S315000199A0B8011BE5C4111BE5006061E0E8FFFFEAB1\r
+S315000199B0B8C11BE5C4E11BE53050A0E30C406EE0E5\r
+S315000199C03CC79FE528E04BE2B4011BE5014044E2B8\r
+S315000199D00C50CEE72CE79FE5020054E30240A0239A\r
+S315000199E028C04BE20EA0CCE70420A0E15D1F4BE2AC\r
+S315000199F0633F4BE28C410BE59CFCFFEB000050E31F\r
+S31500019A0089FFFF1A8C311BE5010053E3AAFFFF9A78\r
+S31500019A10C4E11BE502E08EE2C4E10BE5DEFEFFEAEE\r
+S31500019A20B8011BE5C4111BE5623F4BE200C061E0D2\r
+S31500019A3001C04CE201005CE301C0A0230C20A0E1BF\r
+S31500019A40B4011BE529104BE288C10BE587FCFFEB4E\r
+S31500019A50000050E374FFFF1A88311BE5000053E351\r
+S31500019A60C4211B1501208212C4210B15CAFEFF1A3F\r
+S31500019A706DFFFFEAB8111BE5C4211BE5016062E039\r
+S31500019A80ADFEFFEAA531A0E1861E83E1A621A0E194\r
+S31500019A90070005E20260A0E10150A0E1300080E28A\r
+S31500019AA006E095E1010067E5F5FFFF1AC0111BE528\r
+S31500019AB0010011E30300000A300050E33030A01327\r
+S31500019AC00000000A013067E528004BE2003067E03C\r
+S31500019AD0043043E2D4310BE569FEFFEA020052E3AA\r
+S31500019AE063FEFF1A2512A0E1D8C11BE50F2005E28E\r
+S31500019AF0063E81E12642A0E10200DCE70460A0E126\r
+S31500019B000350A0E106E095E1010067E5F4FFFF1AC5\r
+S31500019B10ECFFFFEA000056E31400009A0610A0E1EC\r
+S31500019B200500A0E10030A0E30A20A0E3791000EBD4\r
+S31500019B30300080E2010067E50030A0E30A20A0E3DF\r
+S31500019B400610A0E10500A0E1DD0E00EB0160A0E139\r
+S31500019B500050A0E1000056E3EFFFFF8A0100001A62\r
+S31500019B60090050E3ECFFFF8A303085E2D4FFFFEABB\r
+S31500019B70FCFFFF1A090055E3E7FFFF8AF9FFFFEA39\r
+S31500019B802D30A0E329304BE5005075E20060E6E296\r
+S31500019B9023FEFFEAC0211BE5100012E30F00001AA5\r
+S31500019BA0C0C11BE540001CE30500000ABC311BE5F2\r
+S31500019BB0F050D3E104E083E2C56FA0E1BCE10BE51F\r
+S31500019BC015FEFFEAC0011BE5020C10E3BC311B15B3\r
+S31500019BD00410831200209315BC110B150200001A04\r
+S31500019BE0BC311BE5042093E4BC310BE50250A0E136\r
+S31500019BF0C56FA0E108FEFFEAC0311BE50010D8E5FC\r
+S31500019C00083083E3B7FDFFEAC0E11BE510E08EE310\r
+S31500019C10C0E10BE5C0011BE5200010E30700000AC7\r
+S31500019C20BC311BE5600093E8081083E2BC110BE52B\r
+S31500019C300020A0E30030A0E329304BE5F9FDFFEA5F\r
+S31500019C40C0211BE5100012E30F00001AC0C11BE57D\r
+S31500019C5040001CE30500000ABC311BE5B050D3E10E\r
+S31500019C6004E083E20060A0E3BCE10BE5EFFFFFEA5D\r
+S31500019C70C0011BE5020C10E3BC311B150410831255\r
+S31500019C8000209315BC110B150200001ABC311BE50F\r
+S31500019C90042093E4BC310BE50250A0E10060A0E38F\r
+S31500019CA0E2FFFFEAC0211BE5102082E3C0210BE59C\r
+S31500019CB0C0311BE5200013E30500000ABC311BE59A\r
+S31500019CC0600093E808C083E2BCC10BE50120A0E374\r
+S31500019CD0D7FFFFEAC0E11BE510001EE3BC311B15EF\r
+S31500019CE00400831200209315BC010B151200001A03\r
+S31500019CF0C0111BE5400011E30500000ABC311BE55C\r
+S31500019D00B050D3E1042083E20060A0E3BC210BE55F\r
+S31500019D10EDFFFFEAC0311BE5020C13E3BC311B1555\r
+S31500019D20BC311B0504C0831204E083020020931595\r
+S31500019D3000209305BCC10B15BCE10B050250A0E147\r
+S31500019D400060A0E3E0FFFFEABC039FE5D8010BE555\r
+S31500019D50C0211BE5200012E30B00000ABC311BE504\r
+S31500019D60600093E8083083E2BC310BE5C0E11BE5F6\r
+S31500019D700220A0E301001EE3ADFFFF0A060095E104\r
+S31500019D8002E08E11C0E10B15A9FFFFEAC0C11BE578\r
+S31500019D9010001CE3BC311B1504E08312002093154F\r
+S31500019DA0BCE10B151200001AC0011BE5400010E3CF\r
+S31500019DB00500000ABC311BE5B050D3E1041083E273\r
+S31500019DC00060A0E3BC110BE5E7FFFFEAC0211BE53C\r
+S31500019DD0020C12E3BC311B15BC311B050020931587\r
+S31500019DE004C083020430831200209305BC310B1595\r
+S31500019DF0BCC10B050250A0E10060A0E3DAFFFFEA57\r
+S31500019E00BC311BE5177E4BE20020D3E501C0A0E380\r
+S31500019E10043083E2BC310BE5D4C10BE50020C7E574\r
+S31500019E200030A0E329304BE595FDFFEABC311BE587\r
+S31500019E300F0059E308C083E2030093E8BCC10BE5B8\r
+S31500019E40200000DA67005AE347005A130200001A9D\r
+S31500019E50C0E11BE501001EE30100000A0F9049E283\r
+S31500019E60DC910BE50F90A0E3177E4BE20030A0E3F7\r
+S31500019E700030C7E5534FE0E328304BE204E083E0CE\r
+S31500019E802CC04BE2C0311BE50920A0E10CC08DE5D9\r
+S31500019E9008708DE500E08DE504A08DE5150100EB68\r
+S31500019EA028C04BE2D4010BE50430DCE7000053E3A4\r
+S31500019EB02D30A01329304B150030D7E5000053E3B0\r
+S31500019EC0017087026EFDFFEA010079E30690A003A7\r
+S31500019ED0E4FFFFEAC0C11BE50010D8E540C08CE3F2\r
+S31500019EE0C0C10BE593FCFFEA0010D8E56C0051E315\r
+S31500019EF0C0011B1510008013C0010B158DFCFF1A44\r
+S31500019F00C0E11BE50110F8E520E08EE304FDFFEA60\r
+S31500019F10C0E11BE520001EE31D00001AC0E11BE5A0\r
+S31500019F2010001EE30B00001AC0211BE5400012E3DE\r
+S31500019F300F00001AC0E11BE5020C1EE30500001A22\r
+S31500019F40BC311BE5C4C11BE5042093E4BC310BE520\r
+S31500019F5000C082E554FCFFEABC311BE5C4111BE5D8\r
+S31500019F60002093E5040083E2BC010BE5001082E5C5\r
+S31500019F704DFCFFEABC311BE501CC4BE2002093E529\r
+S31500019F80B4CC5CE1043083E2BC310BE5B0C0C2E184\r
+S31500019F9045FCFFEABC311BE5BCC11BE5000093E5AE\r
+S31500019FA0C4311BE504C08CE20310A0E1C12FA0E17E\r
+S31500019FB0BCC10BE5060080E83BFCFFEABC311BE5B2\r
+S31500019FC0C0011BE5002093E540C19FE50250A0E1D9\r
+S31500019FD00060A0E30220A0E304E083E2020080E146\r
+S31500019FE078A0A0E3D8C10BE5BCE10BE5C0010BE508\r
+S31500019FF00FFFFFEAC0211BE50010D8E5202082E310\r
+S3150001A000EEFCFFEABC311BE5007093E5041083E228\r
+S3150001A010FC309FE5000057E30370A001000059E3FF\r
+S3150001A020BC110BE50B0000BA0700A0E10010A0E38C\r
+S3150001A0300920A0E1F80200EB000050E30300000A4A\r
+S3150001A040000067E0090050E1D4010BE573FFFFDA78\r
+S3150001A050D4910BE571FFFFEA0700A0E12F0300EBA6\r
+S3150001A060D4010BE56DFFFFEAA0109FE5D8110BE5C2\r
+S3150001A07036FFFFEA00005AE3EBFDFF0A0030A0E3DA\r
+S3150001A080177E4BE200A0C7E529304BE5013083E29C\r
+S3150001A0908FFEFFEAC0211BE50010D8E5022C82E302\r
+S3150001A0A0C6FCFFEAC4011BE5B8E11BE50710A0E108\r
+S3150001A0B00EC060E001C04CE205005CE105C0A021D4\r
+S3150001A0C00C20A0E1B4011BE55F3F4BE27CC10BE52F\r
+S3150001A0D0E6FAFFEB000050E3D3FDFF1A7C311BE5E6\r
+S3150001A0E0050053E1C4211B2505208220C4210B252F\r
+S3150001A0F0FEFBFF2AE4FDFFEAA8120200402102004E\r
+S3150001A10050210200B4FEFFFFB5FEFFFF70110200F1\r
+S3150001A11090110200C41202000DC0A0E1F0DD2DE98C\r
+S3150001A12004B04CE208D04DE20280A0E10350A0E168\r
+S3150001A130412F8FE20C0092E80170A0E10060A0E1DE\r
+S3150001A1409D1300EB000050E304409BE50CA09BE54A\r
+S3150001A1500800DBE53000001A300040E2321400EB63\r
+S3150001A16030304BE2030083E930C04BE2D0208FE26E\r
+S3150001A1700C0092E803009CE9B61300EB000050E3E3\r
+S3150001A180170000DA3010A0E30020D4E52E0052E3D8\r
+S3150001A19001207405012082E2FF3002E2390053E317\r
+S3150001A1A00020C4E50C00009A050054E1011044E4C6\r
+S3150001A1B0F4FFFF1A000058E33130A00301304505D2\r
+S3150001A1C0015045020400000A3120A0E30020C5E544\r
+S3150001A1D0003098E5013083E2003088E50500A0E112\r
+S3150001A1E0F0AD1BE90030DAE52D0053E3FAFFFF1A63\r
+S3150001A1F00010A0E30020D4E52E0052E301207405EF\r
+S3150001A200FF3002E2300053E3F3FFFF1A050054E189\r
+S3150001A210014044E20010CA05F5FFFFEA28208FE25B\r
+S3150001A2200C0092E80710A0E10600A0E1631100EB23\r
+S3150001A2302C204BE2EE0200EBCAFFFFEA0000000011\r
+S3150001A2400000000000001040000000000000244053\r
+S3150001A2500000000010402DE9000051E30120C0E498\r
+S3150001A2602D30A0B32B30A0A301C0A0E100C061B284\r
+S3150001A2700130C0B40130C0A409005CE33030A0D382\r
+S3150001A2804DDF4DE20130C0D403208CD04DEF8DE27D\r
+S3150001A2900120C0D4140000DA54409FE5942CC3E099\r
+S3150001A2A0CC2FA0E1432162E0021182E081104CE053\r
+S3150001A2B0301081E2090052E302C0A0E101106EE50F\r
+S3150001A2C0F5FFFFCA303082E201306EE54D3F8DE287\r
+S3150001A2D003005EE10400002A0130DEE44D2F8DE229\r
+S3150001A2E002005EE10130C0E4FAFFFF3A4DDF8DE284\r
+S3150001A2F01080BDE8676666660DC0A0E1F0DF2DE956\r
+S3150001A30004B04CE22CD04DE20280A0E104209BE592\r
+S3150001A3100150A0E10040A0E1000050E30040A0E3AD\r
+S3150001A32040300BE50170A0E10060A0E10040C2E50C\r
+S3150001A330050000AA281400EB04C09BE52D30A0E31C\r
+S3150001A3400170A0E10060A0E10030CCE50710A0E1BA\r
+S3150001A3500600A0E1950200EB000050E30E02000AA0\r
+S3150001A3600C309BE50710A0E10600A0E1013083E275\r
+S3150001A37030204BE248400BE50C308BE53C400BE5C9\r
+S3150001A3809B0200EB10C09BE50C709BE501A0A0E1D0\r
+S3150001A3900090A0E101604CE230104BE2300091E800\r
+S3150001A3A09F2F8FE20C0092E80510A0E10400A0E1C6\r
+S3150001A3B0011300EB00C0A0E100005CE3252E8FE253\r
+S3150001A3C00C0092E80510A0E10400A0E11100000ACA\r
+S3150001A3D00F1200EB30204BE2850200EB38C04BE256\r
+S3150001A3E003008CE8222E8FE20C0092E8AE1000EBFF\r
+S3150001A3F0872F8FE20C0092E8F01000EBBA1300EB06\r
+S3150001A4003C301BE5300080E2014083E2010046E476\r
+S3150001A4103C400BE5DFFFFFEA08209BE5453042E2C1\r
+S3150001A420220053E303F19F97680000EA2CA601007E\r
+S3150001A430D0A5010038A90100D0A50100D0A50100D1\r
+S3150001A440D0A50100D0A50100D0A50100D0A501002D\r
+S3150001A450D0A50100D0A50100D0A50100D0A501001D\r
+S3150001A460D0A50100D0A50100D0A50100D0A501000D\r
+S3150001A470D0A50100D0A50100D0A50100D0A50100FD\r
+S3150001A480D0A50100D0A50100D0A50100D0A50100ED\r
+S3150001A490D0A50100D0A50100D0A50100D0A50100DD\r
+S3150001A4A0D0A50100D0A50100D0A501002CA6010070\r
+S3150001A4B0B8A4010038A901003C301BE5000053E3B4\r
+S3150001A4C00C709B053030A0030130C7040800000A58\r
+S3150001A4D010309BE5016086E2030056E10400002A84\r
+S3150001A4E00130D6E410C09BE50130C7E40C0056E10B\r
+S3150001A4F0FAFFFF3A000058E30200001A40101BE57C\r
+S3150001A500010011E30100000A2E30A0E30130C7E487\r
+S3150001A510432F8FE20C0092E80A10A0E10900A0E1A6\r
+S3150001A520A51200EB000050E32000000A000058E3EA\r
+S3150001A5301700000A38504BE2D4208FE20C0092E853\r
+S3150001A5400A10A0E10900A0E19C1000EB0520A0E1A2\r
+S3150001A550270200EB01A0A0E10090A0E1030095E82D\r
+S3150001A560611300EB00C0A0E130C08CE2018058E22B\r
+S3150001A570AC208FE20C0092E80A10A0E10900A0E1EC\r
+S3150001A58001C0C7E40200000A8B1200EB000050E391\r
+S3150001A590E8FFFF1A88208FE20C0092E80A10A0E17A\r
+S3150001A5A00900A0E1841200EB000050E30A00001A42\r
+S3150001A5B0018048E2010078E30400000A3030A0E39C\r
+S3150001A5C0018048E2010078E30130C7E4FBFFFF1A8E\r
+S3150001A5D00C109BE5070061E0F0AF1BE901C047E203\r
+S3150001A5E00040A0E300C08DE504C09BE50A10A0E190\r
+S3150001A5F00900A0E10420A0E10C309BE510108DE9D3\r
+S3150001A600C4FEFFEB0C008BE5E8FFFFEAE17A843F2D\r
+S3150001A6107B14AE470000244000000000E2361A3FDA\r
+S3150001A6202D431CEB00000000000000003C401BE530\r
+S3150001A630000054E38600000A0130F6E50C709BE544\r
+S3150001A640000058E30130C7E40200001A40101BE580\r
+S3150001A650010011E30300000A0C209BE52E30A0E364\r
+S3150001A6600130C2E5017087E2000058E30D00000ADF\r
+S3150001A67010309BE5016086E2030056E10700002ADF\r
+S3150001A6800030D6E5018058E20130C7E40500000A32\r
+S3150001A69010C09BE5016086E20C0056E1F7FFFF3A28\r
+S3150001A6A0000058E30300001A10109BE5016086E2E2\r
+S3150001A6B0010056E15700003A3C301BE5014043E2F8\r
+S3150001A6C03C400BE5A8204FE20C0092E80A10A0E1FD\r
+S3150001A6D00900A0E1381200EB000050E32000000A57\r
+S3150001A6E0000058E31700000A38504BE2E0204FE221\r
+S3150001A6F00C0092E80A10A0E10900A0E12F1000EB7E\r
+S3150001A7000520A0E1BA0100EB01A0A0E10090A0E1C3\r
+S3150001A710030095E8F41200EB00C0A0E130C08CE222\r
+S3150001A720018058E2422F4FE20C0092E80A10A0E1A4\r
+S3150001A7300900A0E101C0C7E40200000A1E1200EBF5\r
+S3150001A740000050E3E8FFFF1A4B2F4FE20C0092E89E\r
+S3150001A7500A10A0E10900A0E1171200EB000050E386\r
+S3150001A7601F00001A018048E2010078E30400000A94\r
+S3150001A7703030A0E3018048E2010078E30130C7E40C\r
+S3150001A780FBFFFF1A48101BE5000051E30E00000A0B\r
+S3150001A79040201BE5013022E2010013E30A00000A12\r
+S3150001A7A00C309BE5030057E10030D7950200009A73\r
+S3150001A7B0013077E5300053E3F8FFFF0AFF3003E28B\r
+S3150001A7C02E0053E301704702017087E20700A0E102\r
+S3150001A7D03C101BE508209BE59DFEFFEB0070A0E108\r
+S3150001A7E07AFFFFEA01C047E200C08DE504C09BE5A0\r
+S3150001A7F000E0A0E30A10A0E10900A0E13C204BE241\r
+S3150001A8000C309BE504E08DE508C08DE541FEFFEBCC\r
+S3150001A8100C008BE5D2FFFFEA01C047E2029C4FE242\r
+S3150001A820000699E800E0D6E500C08DE504C09BE589\r
+S3150001A8303C204BE20C309BE50A10A0E10900A0E1A7\r
+S3150001A84004E08DE508C08DE532FEFFEB0C008BE5DB\r
+S3150001A85098FFFFEA8E2F4FE20C0092E80A10A0E162\r
+S3150001A8600900A0E1D41100EB000050E32400000A26\r
+S3150001A8700040E0E338504BE23C400BE50560A0E1C7\r
+S3150001A8809D2F4FE20C0092E80A10A0E10900A0E119\r
+S3150001A890CA0F00EB0520A0E1550100EB0A2D4FE29E\r
+S3150001A8A00C0092E801A0A0E10090A0E1030095E868\r
+S3150001A8B0C11100EB000050E33C301B05014043028F\r
+S3150001A8C03C400B05EDFFFF0A030096E8861200EBFC\r
+S3150001A8D00C709BE5300080E2000058E30100C7E4FC\r
+S3150001A8E00200001A40101BE5010011E374FFFF0A84\r
+S3150001A8F00C209BE52E30A0E3017087E20130C2E512\r
+S3150001A9006FFFFFEA0C709BE53030A0E3000058E3CF\r
+S3150001A9100130C7E40200001A40301BE5010013E3D1\r
+S3150001A92067FFFF0A0CC09BE52E30A0E30130CCE5A2\r
+S3150001A930017087E262FFFFEA000058E33C501BE525\r
+S3150001A94001808802080055E10540A0E18B0000CA9C\r
+S3150001A950000055E31200001ACF2F4FE20C0092E8D7\r
+S3150001A9600A10A0E10900A0E1931100EB000050E3F9\r
+S3150001A9700600000A0A10A0E10900A0E1DA2F4FE261\r
+S3150001A9800C0092E8011200EB000050E37B0000BAD4\r
+S3150001A990000055E30C709B053030A0030130C7045D\r
+S3150001A9A00900000A10209BE5016086E2020056E1DB\r
+S3150001A9B00500002A0130D6E410C09BE5018048E27B\r
+S3150001A9C00C0056E10130C7E4F9FFFF3A000058E3F5\r
+S3150001A9D040201B15016002120300001A40101BE5FE\r
+S3150001A9E0016011E244800B050300000A2E30A0E34A\r
+S3150001A9F00130C7E42D3043E244300BE53E2E4FE2F1\r
+S3150001AA000C0092E80A10A0E10900A0E16A1100EB2E\r
+S3150001AA10000050E33400000A000058E32B00000A4E\r
+S3150001AA2038504BE21E2E8FE20C0092E80A10A0E18C\r
+S3150001AA300900A0E1610F00EB0520A0E1EC0000EBAD\r
+S3150001AA4001A0A0E10090A0E1030095E8261200EB29\r
+S3150001AA50300080E20100C7E4030095E81B2E8FE277\r
+S3150001AA600C0092E82D1100EB000050E3ECFFFF0A09\r
+S3150001AA70018058E2662F8FE20C0092E80A10A0E1ED\r
+S3150001AA800900A0E11100000A4B1100EB00C0A0E192\r
+S3150001AA9000005CE3172E8FE20C0092E80A10A0E199\r
+S3150001AAA00900A0E10900000A440F00EB0520A0E11E\r
+S3150001AAB0CF0000EB01A0A0E10090A0E1030095E822\r
+S3150001AAC0091200EB300080E20100C7E4E7FFFFEA6C\r
+S3150001AAD04F2F8FE20C0092E80A10A0E10900A0E1D5\r
+S3150001AAE0351100EB000050E31800001A000056E390\r
+S3150001AAF00800000A018048E2010078E3B3FEFF0A7C\r
+S3150001AB003030A0E3018048E2010078E30130C7E478\r
+S3150001AB10FBFFFF1AADFEFFEA44101BE5000051E3FF\r
+S3150001AB20AAFEFF0A0C209BE5020057E10030D795EB\r
+S3150001AB300200009A013077E5300053E3F8FFFF0A7F\r
+S3150001AB40FF3003E22E0053E3017087129FFEFFEAF6\r
+S3150001AB5001C047E20040A0E300C08DE504C09BE5CB\r
+S3150001AB600A10A0E10900A0E10420A0E10C309BE558\r
+S3150001AB7010108DE967FDFFEB0C008BE5DAFFFFEAAC\r
+S3150001AB8008C09BE50110A0E302C04CE2018048E247\r
+S3150001AB9008C08BE548100BE5A4FEFFEA08C09BE55B\r
+S3150001ABA00710A0E10600A0E165304CE2020053E384\r
+S3150001ABB02040A0930040A083810000EB000050E3F9\r
+S3150001ABC00800000A0C709BE54E2084E20120C7E4D0\r
+S3150001ABD00C109BE5413084E2017087E20130C1E54A\r
+S3150001ABE00120C7E479FEFFEA0C709BE5493084E257\r
+S3150001ABF00130C7E40CC09BE54E3084E2462084E276\r
+S3150001AC00017087E20130CCE5F4FFFFEA0000244041\r
+S3150001AC10000000000000000000000000030052E3F5\r
+S3150001AC2070402DE902C0A0E1FF1001E20400009A84\r
+S3150001AC30033010E20320A00100E0A0010340A001BF\r
+S3150001AC400B00000A01C04CE201007CE30600000A89\r
+S3150001AC500030D0E501C04CE2010053E17080BD082F\r
+S3150001AC6001007CE3010080E2F8FFFF1A0000A0E387\r
+S3150001AC707080BDE8012082E2030052E3044481E0D2\r
+S3150001AC80FBFFFF9A04005CE31600009A84309FE5FF\r
+S3150001AC9084209FE5006093E5005092E500209EE543\r
+S3150001ACA0042022E0023066E00230C3E1050013E130\r
+S3150001ACB00800000A0E00A0E10020A0E30030D0E564\r
+S3150001ACC0012082E2010053E17080BD08030052E3D6\r
+S3150001ACD0010080E2F8FFFF9A04C04CE204005CE345\r
+S3150001ACE004E08EE2ECFFFF8A01C04CE201007CE346\r
+S3150001ACF00E00A0E1DCFFFF0A0030D0E501C04CE206\r
+S3150001AD00010053E17080BD0801007CE3010080E28F\r
+S3150001AD10F8FFFF1AD4FFFFEACC120200D412020098\r
+S3150001AD20030010E304E02DE500E0A0E10700000ABE\r
+S3150001AD300030D0E5000053E30200000A0130F0E5DF\r
+S3150001AD40000053E3FCFFFF1A00006EE004F09DE4EF\r
+S3150001AD5050309FE5001090E500C093E548209FE53F\r
+S3150001AD6001306CE0002092E50130C3E1020013E1FD\r
+S3150001AD700500001A0210A0E10420B0E502306CE0E3\r
+S3150001AD800230C3E1010013E1FAFFFF0A0030D0E50A\r
+S3150001AD90000053E3EBFFFF0A0130F0E5000053E347\r
+S3150001ADA0FCFFFF1AE7FFFFEACC120200D4120200F1\r
+S3150001ADB00201C0E3020180E2010680E2A00FA0E1E8\r
+S3150001ADC00EF0A0E108D04DE203008DE809009DE8F0\r
+S3150001ADD0002063E2023083E10201C0E3A30F80E1B8\r
+S3150001ADE07F0460E20F0680E2A00FA0E108D08DE2A9\r
+S3150001ADF00EF0A0E10DC0A0E170D82DE904B04CE23F\r
+S3150001AE0020304BE208D04DE20260A0E1030083E866\r
+S3150001AE1020C01BE5D8309FE51CE01BE54C3A03E05A\r
+S3150001AE20FF3F43E2033043E2130053E31E0000CA2F\r
+S3150001AE30000053E3160000BAB8209FE55223A0E1B3\r
+S3150001AE4002300CE00EE093E102310C0220300B05DA\r
+S3150001AE501CE00B050A00000A0230CCE10020A0E349\r
+S3150001AE60003086E5042086E50C0096E8260E00EB08\r
+S3150001AE700150A0E10040A0E10510A0E10400A0E11D\r
+S3150001AE8070A81BE920304BE2300093E8030086E806\r
+S3150001AE90F8FFFFEA02210CE20030A0E30150A0E135\r
+S3150001AEA00040A0E10C0086E8F2FFFFEA330053E31D\r
+S3150001AEB002310CC20020A0C320300BC51C200BC5DB\r
+S3150001AEC0EFFFFFCA142043E20030E0E33322A0E1A2\r
+S3150001AED002401EE00230CE1100C0861504308615F0\r
+S3150001AEE0E0FFFF1A02310CE220300BE51C400BE5B6\r
+S3150001AEF0E3FFFFEAFF070000FFFF0F000C309FE5AD\r
+S3150001AF00002093E5000093E5880080E20EF0A0E1C1\r
+S3150001AF100C8A02000DC0A0E100D82DE904B04CE274\r
+S3150001AF2030C09FE50020A0E100309CE50010A0E1C3\r
+S3150001AF30000053E3440090050400000A440090E534\r
+S3150001AF40040050E300309C053C30820500A81B0933\r
+S3150001AF50ADE9FFEB00A81BE960B202000EF0A0E12B\r
+S3150001AF600DC0A0E130D82DE924309FE524409FE5AE\r
+S3150001AF7004B04CE2030054E130A81B390350A0E1B0\r
+S3150001AF800FE0A0E104F014E4050054E130A81B39F8\r
+S3150001AF90FAFFFFEA08220200382202000000A0E3BD\r
+S3150001AFA00EF0A0E10020A0E10000A0E35230A0E1F4\r
+S3150001AFB0010013E30EF0A011010080E21F0050E32F\r
+S3150001AFC00000E0C30EF0A0C1F7FFFFEA0020A0E1F8\r
+S3150001AFD01F00A0E35230A0E1010013E30EF0A0111F\r
+S3150001AFE0010050E20000E0430EF0A041F8FFFFEA45\r
+S3150001AFF014C04DE200602CE90CD0A0E1FF1F2DE941\r
+S3150001B00000200FE140208DE500D081E500B090E5FC\r
+S3150001B01000000FE1C00080E300F029E140009BE55C\r
+S3150001B02000F069E1FF7F9BE80EF0B0E1F07F80E878\r
+S3150001B0300000A0E30EF0A0E1F07F90E80100A0E19E\r
+S3150001B0400EF0A0E10DC0A0E100D82DE904B04CE25C\r
+S3150001B050520000EB00681BE91CDCFFEA00100FE15F\r
+S3150001B0601F10C1E3131081E301F029E10010A0E3F1\r
+S3150001B070171F07EE9A1F07EE171F08EE101F11EE96\r
+S3150001B080011AC1E30710C1E3101F01EE0000A0E1A0\r
+S3150001B09000F0A0E1FEFFFFEA2C309FE52CC09FE502\r
+S3150001B0A02C209FE50311A0E3001083E50030A0E307\r
+S3150001B0B0000082E500308CE518209FE518309FE5F9\r
+S3150001B0C0002083E500008CE50EF0A0E108800680F3\r
+S3150001B0D030800680E4AF0200CC400000208006806C\r
+S3150001B0E01C309FE51C209FE50209A0E3000083E5D3\r
+S3150001B0F0001082E54231A0E30110A0E3001083E5D0\r
+S3150001B1000EF0A0E128800680E4AF020014309FE52E\r
+S3150001B11014209FE5B210D3E1003092E5033061E0DF\r
+S3150001B120003080E50EF0A0E130800680E4AF020039\r
+S3150001B1300DC0A0E170D82DE9803080E004B04CE26A\r
+S3150001B14008D04DE28351A0E11C004BE2EEFFFFEB7C\r
+S3150001B150000055E30040A0E370A81B9920604BE274\r
+S3150001B1600600A0E1E8FFFFEB20001BE51C101BE534\r
+S3150001B170010050E120209F350030612000309235DA\r
+S3150001B1801C000BE50330613000308330034084E05E\r
+S3150001B190040055E170A81B99F0FFFFEAE4AF020035\r
+S3150001B1A00DC0A0E110D82DE904B04CE20040A0E3A7\r
+S3150001B1B00400A0E1014084E2100000EB3F0054E3EB\r
+S3150001B1C010A81BC9F9FFFFEA2C209FE502C1A0E3E5\r
+S3150001B1D0001092E54000A0E3000051E300309C0519\r
+S3150001B1E00030A013C32FA001223F83004301A00119\r
+S3150001B1F00030821500108C050EF0A0E160210200DE\r
+S3150001B200C01FA0E1211F80E04111A0E1010140E042\r
+S3150001B2108001A0E10430A0E308209FE51330A0E1FE\r
+S3150001B220013282E70EF0A0E168000080C01FA0E1B4\r
+S3150001B230211F80E04111A0E1010140E08001A0E170\r
+S3150001B2400430A0E308209FE51330A0E1013282E734\r
+S3150001B2500EF0A0E1640000800EF0A0E10EF0A0E186\r
+S3150001B2600EF0A0E10EF0A0E104402DE50030A0E3D0\r
+S3150001B270003080E50040A0E30030A0E30C1080E53B\r
+S3150001B280180080E91000BDE80EF0A0E104402DE5AC\r
+S3150001B2900030A0E3003080E50040A0E30030A0E3E9\r
+S3150001B2A00C1080E5180080E91000BDE80EF0A0E161\r
+S3150001B2B0003090E504E02DE5000053E304F09D0421\r
+S3150001B2C000E0A0E3001053E204F09D0400C091E504\r
+S3150001B2D001005CE1043091150E10A00104308C15BB\r
+S3150001B2E0042091150410811500C0821500108115E6\r
+S3150001B2F00C10A01100E0800500C08015000051E38C\r
+S3150001B30004F09D04F0FFFFEA003090E504E02DE52E\r
+S3150001B310000053E304F09D0400E0A0E3001053E2B3\r
+S3150001B32004F09D0400C091E501005CE10430911533\r
+S3150001B3300E10A00104308C150420911504108115FE\r
+S3150001B34000C08215001081150C10A01100E08005C7\r
+S3150001B35000C08015000051E304F09D04F0FFFFEAF0\r
+S3150001B3600DC0A0E1F0D82DE9017041E2010077E3BB\r
+S3150001B37004B04CE20060A0E1F0A81B095C219FE546\r
+S3150001B380003092E5013083E2003082E5060096E95D\r
+S3150001B3900C0096E5003091E00040A2E2180086E933\r
+S3150001B3A0000096E500E0A0E3005050E21300000A19\r
+S3150001B3B014C085E2083096E504209CE5001095E569\r
+S3150001B3C0030052E10600008A083096E5030052E1C7\r
+S3150001B3D01A00001A042096E5143095E5020053E19F\r
+S3150001B3E01500009A000051E11100000A010055E123\r
+S3150001B3F00150A0E10E00000A000055E3EBFFFF1A21\r
+S3150001B40000005EE3E5FFFF1AD0209FE5003092E5DC\r
+S3150001B410010053E2000082150300000A017047E2B1\r
+S3150001B420010077E3F0A81B09D3FFFFEA43EBFFEB2B\r
+S3150001B430F9FFFFEA0050A0E3EEFFFFEA043096E5CC\r
+S3150001B440000055E104309515043081150420951549\r
+S3150001B4500450851500108215005085151400000A48\r
+S3150001B4601C1085E21C0095E5043091E5030090E18E\r
+S3150001B4700600001A240085E5101095E50500A0E1F7\r
+S3150001B4800FE0A0E10CF095E501E0A0E3DBFFFFEAA8\r
+S3150001B490060091E818009CE80600A0E1013093E05F\r
+S3150001B4A00240A4E018008CE80510A0E10C0000EBB6\r
+S3150001B4B0F0FFFFEA050051E1043095150030A003C5\r
+S3150001B4C0043081150420951500308605001082157B\r
+S3150001B4D0045085150050851500108615DFFFFFEA1B\r
+S3150001B4E0F42002000DC0A0E1F0D82DE90130A0E35F\r
+S3150001B4F0243081E5147081E2042097E5083090E557\r
+S3150001B50004B04CE2030052E10150A0E10060A0E169\r
+S3150001B5101800008A083090E5030052E11F00000A76\r
+S3150001B520101095E50500A0E10FE0A0E10CF095E50E\r
+S3150001B5301C1085E21C2095E5043091E5032092E17B\r
+S3150001B5400200000A243095E5000053E30200001AC8\r
+S3150001B5500030A0E3243085E5F0A81BE9180097E840\r
+S3150001B560060091E80500A0E1013093E00240A4E065\r
+S3150001B570180087E8E40200EB001096E5000051E3AD\r
+S3150001B5800430911500108515043085150420911598\r
+S3150001B590005086050450811500508215F0A81BE95C\r
+S3150001B5A0142091E5043090E5030052E1F1FFFF8A92\r
+S3150001B5B0043090E5D9FFFFEA003090E501C0A0E133\r
+S3150001B5C0030051E1003091150420911504208315E3\r
+S3150001B5D00410911504C08C150030811500C08C151E\r
+S3150001B5E00200000A0030A0E324308CE50EF0A0E151\r
+S3150001B5F0000051E3FAFFFF0A001091E50C0051E14A\r
+S3150001B60004309C150030A0030430811504209C15DC\r
+S3150001B610003080050010821504C08C1500C08C1501\r
+S3150001B62000108015EEFFFFEA0DC0A0E170D82DE9EC\r
+S3150001B6300260A0E10150A0E104B04CE20110A0E3D8\r
+S3150001B6400040A0E107FFFFEB104084E2600084E8C0\r
+S3150001B65070A81BE90DC0A0E170D82DE90260A0E138\r
+S3150001B6600150A0E104B04CE20110A0E30040A0E1CA\r
+S3150001B670FCFEFFEB104084E2600084E870A81BE941\r
+S3150001B68004E02DE504E09DE408FFFFEA04E02DE572\r
+S3150001B69004E09DE405FFFFEA0DC0A0E104D04DE200\r
+S3150001B6A0F0DF2DE908B04CE238D04DE230C04BE274\r
+S3150001B6B004308BE50C308BE2300093E802A0A0E168\r
+S3150001B6C00190A0E130000CE814C08BE218009CE860\r
+S3150001B6D040504BE2180085E93CE01BE534301BE5A0\r
+S3150001B6E004C09BE5991382E09C4E85E040304BE215\r
+S3150001B6F050C04BE2060003E830008CE90230A0E1BD\r
+S3150001B70030101BE504209BE538401BE5913923E009\r
+S3150001B710945222E00EC0A0E134501BE508E09BE5FF\r
+S3150001B7209A3525E09E2C2CE02C000BE50000A0E3C9\r
+S3150001B73040500BE548C00BE554000BE540104BE2C9\r
+S3150001B740180011E80060A0E30150A0E3053003E012\r
+S3150001B750064004E0043093E11D00001A50204BE23C\r
+S3150001B760180092E9053003E0064004E0043093E155\r
+S3150001B7701700001A44301BE540E01BE5A320A0E1B9\r
+S3150001B7808E3F82E1AE40A0E140104BE2180001E895\r
+S3150001B7904CC01BE540304BE2060013E8AC00A0E1CB\r
+S3150001B7A048C01BE5051001E0062002E08C3F80E160\r
+S3150001B7B0AC40A0E150E04BE2021091E118008EE9A5\r
+S3150001B7C0053003E0064004E00100001A043093E16D\r
+S3150001B7D0E7FFFF0A0010A0E350100BE550301BE510\r
+S3150001B7E040404BE28320A0E1EC369FE5030014E8DC\r
+S3150001B7F0B36092E10070A0E30730A0E10620A0E16A\r
+S3150001B800AF0700EB0190A0E10080A0E1981682E06D\r
+S3150001B810972823E044501BE5993622E0050051E1C3\r
+S3150001B8208101000A50001BE5010080E22F0050E370\r
+S3150001B83050000BE5E8FFFF9A40104BE2000611E8C5\r
+S3150001B84050104BE20030A0E30120A0E340404BE260\r
+S3150001B850030091E90C0084E900005AE330404BE211\r
+S3150001B86003008BE90C0004E80200008AF800001AC4\r
+S3150001B870010859E3F600009A04E09BE508C09BE540\r
+S3150001B88038001BE5AE30A0E18020A0E100005CE1BC\r
+S3150001B890AC10A0E18C0F83E104C09BE53CE01BE505\r
+S3150001B8A001302CE2AE5F82E18E40A0E1013003E27D\r
+S3150001B8B00020A0E30200008A0200001A0E005CE1EB\r
+S3150001B8C00000009A0120A0E3023013E040C04B12B1\r
+S3150001B8D003008B1930008C19E6FFFF1A08E09BE57F\r
+S3150001B8E038001BE503C0A0E100005EE10400008A08\r
+S3150001B8F00400001A04109BE53C201BE5020051E1FF\r
+S3150001B9000000009A01C0A0E30030A0E300005CE360\r
+S3150001B91050300BE51D00000A50401BE5B8359FE588\r
+S3150001B9208420A0E1B35092E103009BE90060A0E30B\r
+S3150001B9300630A0E10520A0E160C00BE5600700EB41\r
+S3150001B94060C01BE500005CE30500000A907588E015\r
+S3150001B950968023E004E09BE5913528E00E0057E14F\r
+S3150001B9600C01000A50301BE5013083E250300BE533\r
+S3150001B9702F0053E30030A0830130A09300005CE365\r
+S3150001B9800030A00301300312000053E3E1FFFF1A68\r
+S3150001B99030009BE9A4CDA0E18502A0E130E01BE5E2\r
+S3150001B9A0013029E20E005AE1013003E20020A0E352\r
+S3150001B9B00300008A0300001A34101BE5010059E157\r
+S3150001B9C00000009A0120A0E3020013E11800000A1A\r
+S3150001B9D000408CE104209BE504005AE18232A0E19B\r
+S3150001B9E00200008A1200001A030059E11000009AB1\r
+S3150001B9F0A920A0E130E01BE58A3F82E1AA40A0E14F\r
+S3150001BA0034201BE504A0A0E10390A0E18E10A0E183\r
+S3150001BA10A24F81E18230A0E130504BE200005AE3AF\r
+S3150001BA20180005E8DCFFFF8A0100001A010859E346\r
+S3150001BA30D9FFFF2A30301BE500C0A0E303005AE11D\r
+S3150001BA400300008A1600001A34401BE5040059E180\r
+S3150001BA501300009A08509BE504E09BE50532A0E13E\r
+S3150001BA602E2E83E102005AE10E12A0E10C00A0E1A4\r
+S3150001BA700200008A0200001A010059E10000009A42\r
+S3150001BA800100A0E300005AE30030A0E30200008AAF\r
+S3150001BA900200001A010859E30000009A0130A0E3F0\r
+S3150001BAA003C000E00010A0E300005CE350100BE5CA\r
+S3150001BAB03300000A50301BE50A10A0E10900A0E19D\r
+S3150001BAC08320A0E110349FE5B36092E160C00BE5ED\r
+S3150001BAD00070A0E30730A0E10620A0E1F80600EB24\r
+S3150001BAE060C01BE50020A0E300005CE31200000A31\r
+S3150001BAF008409BE504C09BE50432A0E12C5E83E18E\r
+S3150001BB00050051E10C42A0E10200008A0200001A80\r
+S3150001BB10040050E10000009A0120A0E3000051E377\r
+S3150001BB200030A0E30200008A0200001A010850E377\r
+S3150001BB300000009A0130A0E3032002E000C052E2B7\r
+S3150001BB400400000A904685E0975023E0090054E17D\r
+S3150001BB50913625E05C00000A50301BE5013083E296\r
+S3150001BB6050300BE52F0053E30030A0830130A09342\r
+S3150001BB7000005CE30030A00301300312000053E330\r
+S3150001BB80CBFFFF1A010019E31000000A44401BE530\r
+S3150001BB900020A0E3040059E14700000A00005AE32F\r
+S3150001BBA00030A0E30200008A0200001A010859E3EE\r
+S3150001BBB00000009A0130A0E3033002E0010013E324\r
+S3150001BBC00200000A54C01BE501005CE3330000DA01\r
+S3150001BBD004409BE5010014E31D00000A4CC01BE56F\r
+S3150001BBE00020A0E30C0054E12700000A08109BE5A1\r
+S3150001BBF00030A0E3000051E30300008A0300001AAD\r
+S3150001BC0004409BE5010854E30000009A0130A0E3DB\r
+S3150001BC10033002E0010013E30D00000A54501BE556\r
+S3150001BC20010055E30A0000CA18009BE90010E0E391\r
+S3150001BC300000E0E3003093E00140A4E050504BE205\r
+S3150001BC40180085E954C01BE501C08CE254C00BE520\r
+S3150001BC50B9FEFFEA2C301BE530009BE90006A3E89C\r
+S3150001BC602CE01BE5300083E830404BE2180014E875\r
+S3150001BC7010208EE2180082E840304BE20C0093E976\r
+S3150001BC8018108EE20C0081E8F0AF1BE908E09BE595\r
+S3150001BC9048001BE500005EE10120A003D2FFFFEA98\r
+S3150001BCA00010E0E30000E0E3090090E00A10A1E0E3\r
+S3150001BCB040304BE2030003E8E2FFFFEA40501BE598\r
+S3150001BCC005005AE10120A003B3FFFFEA0A0055E18E\r
+S3150001BCD0A0FFFF1A34201BE530504BE2923684E078\r
+S3150001BCE0974222E030401BE501A0A0E10090A0E1CF\r
+S3150001BCF0962424E0180005E80730A0E10620A0E11B\r
+S3150001BD006F0600EB04005AE100C0A0E30300008ABD\r
+S3150001BD101600001A34E01BE50E0059E11300009AE3\r
+S3150001BD2008209BE504E09BE50232A0E12E5E83E15B\r
+S3150001BD30050051E10E42A0E10C20A0E10200008ABB\r
+S3150001BD400200001A040050E10000009A0120A0E35D\r
+S3150001BD50000051E30030A0E30200008A0200001A4D\r
+S3150001BD60010850E30000009A0130A0E303C002E09D\r
+S3150001BD7000005CE377FFFF0A904685E0975023E0D9\r
+S3150001BD80090054E1913625E072FFFF1A0A0055E1D8\r
+S3150001BD90CFFFFF0A6FFFFFEA08209BE5020058E18B\r
+S3150001BDA0EFFEFF1A3CC01BE540E04BE29C3584E008\r
+S3150001BDB00C20A0E1964222E038401BE503008BE906\r
+S3150001BDC0952424E018008EE90630A0E10520A0E1C3\r
+S3150001BDD03B0600EB08209BE500C0A0E3040052E10E\r
+S3150001BDE00400008A0400001A04309BE53C401BE570\r
+S3150001BDF0040053E10000009A01C0A0E300005CE3E7\r
+S3150001BE00D7FEFF0A907588E0968023E004E09BE563\r
+S3150001BE10913528E00E0057E1D1FEFF1A08209BE577\r
+S3150001BE20020058E1DEFFFF0ACDFEFFEA40C01BE536\r
+S3150001BE300C0052E17AFEFF1A50E04BE20730A0E116\r
+S3150001BE400620A0E103009EE91D0600EB60204BE2FF\r
+S3150001BE50904685E0030082E95C101BE54CC01BE5BA\r
+S3150001BE60975121E058501BE50C0054E10730A0E141\r
+S3150001BE700620A0E1961525E069FEFF1A48E01BE5BC\r
+S3150001BE800E0055E166FEFF1A60404BE2300094E970\r
+S3150001BE9050C04BE240004BE2000300E830008CE961\r
+S3150001BEA00910A0E10800A0E1050600EB0190A0E160\r
+S3150001BEB00080A0E1981682E0972823E044C01BE5A4\r
+S3150001BEC0993622E00C0051E155FEFF1A40E01BE5D0\r
+S3150001BED00E0052E1D7FFFF0A51FEFFEA6821020078\r
+S3150001BEE00DC0A0E1F0D82DE904B04CE214D04DE22A\r
+S3150001BEF00CE08DE2106090E5144090E50070A0E33F\r
+S3150001BF000050A0E30300A0E130008DE900C0A0E3EA\r
+S3150001BF10C0008EE80130A0E300C08DE5DDFDFFEB3A\r
+S3150001BF20F0A81BE90DC0A0E1F0DB2DE904B04CE25D\r
+S3150001BF3014D04DE20290A0E10180A0E1146090E5E9\r
+S3150001BF40104090E50070A0E30300A0E10050A0E3DB\r
+S3150001BF500130A0E10CC08DE20020A0E30110A0E3B6\r
+S3150001BF6030008DE9C0008CE800908DE5C9FDFFEB3E\r
+S3150001BF70F0AB1BE910402DE900C0A0E314E080E21C\r
+S3150001BF801C4080E20C2080E5103080E50030A0E303\r
+S3150001BF900020A0E3040080E5000080E524C080E5E0\r
+S3150001BFA0081080E50C008EE80C0084E81080BDE8DE\r
+S3150001BFB010402DE900C0A0E314E080E21C4080E2BD\r
+S3150001BFC00C2080E5103080E50030A0E30020A0E3DE\r
+S3150001BFD0040080E5000080E524C080E5081080E5C6\r
+S3150001BFE00C008EE80C0084E81080BDE8000080E5B6\r
+S3150001BFF0040080E50EF0A0E1000080E5040080E584\r
+S3150001C0000EF0A0E10DC0A0E110D82DE90040A0E19D\r
+S3150001C01004B04CE27E0000EB001094E5040051E10F\r
+S3150001C02010A81B09043094E5043081E5042094E549\r
+S3150001C030044084E5001082E5004084E510A81BE970\r
+S3150001C0400DC0A0E110D82DE90040A0E104B04CE2FA\r
+S3150001C0506F0000EB001094E5040051E110A81B09E4\r
+S3150001C060043094E5043081E5042094E5044084E538\r
+S3150001C070001082E5004084E510A81BE90DC0A0E18F\r
+S3150001C08004D04DE2F0D82DE908B04CE204308BE53E\r
+S3150001C0900040A0E10260A0E10150A0E164709FE5CB\r
+S3150001C0A0003097E5013083E2003087E5243090E5E2\r
+S3150001C0B00010A0E1000053E30F00001A143084E2DF\r
+S3150001C0C01C2084E2080094E50410A0E1600083E8E6\r
+S3150001C0D018009BE9180082E801FDFFEB003097E5A7\r
+S3150001C0E0013053E20300A0E1003087150000000A89\r
+S3150001C0F0F0A81BE911E8FFEBFCFFFFEA080090E559\r
+S3150001C1002CFDFFEBECFFFFEAF42002000DC0A0E1DD\r
+S3150001C110F0DF2DE91C2080E21C3090E504B04CE2F2\r
+S3150001C12004C092E503E0A0E10C309EE114A080E298\r
+S3150001C130F0AF1B09081090E5C00092E8300091E9C4\r
+S3150001C14000039AE8064094E00750A5E0084054E051\r
+S3150001C1500950C5E005005CE10730A0E10620A0E139\r
+S3150001C1600200003AF0AF1B1904005EE1F0AF1B2993\r
+S3150001C1700010E0E30000E0E3004094E00150A5E098\r
+S3150001C1800510A0E10400A0E14D0500EB963084E026\r
+S3150001C190914622E0972024E0038098E00490A9E0EC\r
+S3150001C1A000038AE8F0AF1BE90DC0A0E130D82DE904\r
+S3150001C1B004B04CE20040A0E150509FE5003095E507\r
+S3150001C1C0013083E2003085E5243090E5000053E339\r
+S3150001C1D00700000A003095E5013053E20300A0E1B3\r
+S3150001C1E0003085150000000A30A81BE9D3E7FFEBF4\r
+S3150001C1F0FCFFFFEAC4FFFFEB0130A0E3080094E572\r
+S3150001C200243084E50410A0E1B5FCFFEBF0FFFFEA62\r
+S3150001C210F42002000DC0A0E110D82DE904B04CE2D3\r
+S3150001C22044409FE5003094E5013083E2003084E527\r
+S3150001C230243090E50010A0E1000053E30700001A46\r
+S3150001C240003094E5013053E20300A0E1003084158B\r
+S3150001C2500000000A10A81BE9B8E7FFEBFCFFFFEAA4\r
+S3150001C260080090E5D3FCFFEBF4FFFFEAF42002009F\r
+S3150001C2700DC0A0E130D82DE904B04CE248C09FE5DD\r
+S3150001C28000309CE5013083E200308CE5000051E38B\r
+S3150001C2901C3080E2140080E23000901830008118D2\r
+S3150001C2A0000052E3030093180300821800309CE556\r
+S3150001C2B0013053E20300A0E100308C150000000AB2\r
+S3150001C2C030A81BE99DE7FFEBFCFFFFEAF420020023\r
+S3150001C2D00DC0A0E170D82DE95C309FE508D04DE294\r
+S3150001C2E004B04CE20050A0E1060093E8186080E239\r
+S3150001C2F048409FE5CBFCFFEB44C09FE50530A0E13C\r
+S3150001C3001C10A0E30120A0E30600A0E100C08DE51A\r
+S3150001C31004408DE5E0E4FFEB28009FE55DFBFFEBC4\r
+S3150001C3200600A0E14CE5FFEB1C00A0E3D0E5FFEB26\r
+S3150001C33014309FE5005083E570A81BE9C82102006F\r
+S3150001C340FCC30100D0C30100C05D000064210200EE\r
+S3150001C3500DC0A0E170D82DE95C309FE508D04DE213\r
+S3150001C36004B04CE20050A0E1060093E8186080E2B8\r
+S3150001C37048409FE5ABFCFFEB44C09FE50530A0E1DB\r
+S3150001C3801C10A0E30120A0E30600A0E100C08DE59A\r
+S3150001C39004408DE5C0E4FFEB28009FE53DFBFFEB84\r
+S3150001C3A00600A0E12CE5FFEB1C00A0E3B0E5FFEBE6\r
+S3150001C3B014309FE5005083E570A81BE9C8210200EF\r
+S3150001C3C0FCC30100D0C30100C05D0000642102006E\r
+S3150001C3D00DC0A0E100D82DE918109FE504B04CE28C\r
+S3150001C3E01C00A0E33DFBFFEB1C00A0E3B1E5FFEB66\r
+S3150001C3F00300A0E300A81BE9C05D00000DC0A0E199\r
+S3150001C40000D82DE90200A0E104B04CE2D3FBFFEB1A\r
+S3150001C41004009FE500681BE960E6FFEA148A020052\r
+S3150001C4200DC0A0E1F0D82DE944609FE544709FE579\r
+S3150001C430060051E1010050030040A0E104B04CE2C6\r
+S3150001C4400150A0E10700A0E10700000A060055E13E\r
+S3150001C45000005403180087E2F0A81B199BE4FFEBC8\r
+S3150001C4600700A0E1F0681BE984FCFFEAB7FFFFEBD8\r
+S3150001C470F5FFFFEAB0360000E8AF020004E02DE563\r
+S3150001C48008109FE50100A0E304E09DE4E3FFFFEA55\r
+S3150001C490B036000004E02DE508109FE50000A0E39A\r
+S3150001C4A004E09DE4DDFFFFEAB03600000030A0E3C2\r
+S3150001C4B010402DE9001080E50140A0E1042080E54F\r
+S3150001C4C00C3080E5083080E503E0A0E100C0A0E182\r
+S3150001C4D001E08EE208308CE27F005EE310308CE5ED\r
+S3150001C4E014308CE503C0A0E1F8FFFF9A073014E28F\r
+S3150001C4F0081063120310A001103081E2020053E11B\r
+S3150001C50004309095012084900030A08301308393FC\r
+S3150001C5100030808504308295102080951080BDE81A\r
+S3150001C5200030A0E310402DE9001080E50140A0E1B4\r
+S3150001C530042080E50C3080E5083080E503E0A0E1C9\r
+S3150001C54000C0A0E101E08EE208308CE27F005EE3EC\r
+S3150001C55010308CE514308CE503C0A0E1F8FFFF9A9A\r
+S3150001C560073014E2081063120310A001103081E2B3\r
+S3150001C570020053E104309095012084900030A0839D\r
+S3150001C5800130839300308085043082951020809598\r
+S3150001C5901080BDE8F0472DE90050A0E1000090E5CC\r
+S3150001C5A0000050E30070A0011800000A000051E3EA\r
+S3150001C5B09D0000BA0B1081E2160051E30740C1C38A\r
+S3150001C5C01040A0D37E0F54E3DE00002AA471A0E13F\r
+S3150001C5D0873185E0080083E20CE090E500005EE12A\r
+S3150001C5E00C00000A04309EE50C609EE50120C3E3C1\r
+S3150001C5F002208EE0043092E508009EE5013083E3D7\r
+S3150001C60008708EE2080086E5043082E50C6080E55C\r
+S3150001C6100700A0E1F087BDE808008EE20CE090E596\r
+S3150001C62000005EE1EEFFFF1A027087E218E095E571\r
+S3150001C630108085E208005EE12800000A04309EE5CC\r
+S3150001C6400120C3E302C064E00F005CE30A0000DAE4\r
+S3150001C65004108EE0012084E301308CE308708EE241\r
+S3150001C66004208EE5181085E50CC081E7080181E9F3\r
+S3150001C6701C1085E50C8081E5E4FFFFEA00005CE320\r
+S3150001C6801C8085E5188085E5050000BA02208EE04C\r
+S3150001C690043092E508708EE2013083E3043082E5CE\r
+S3150001C6A0DAFFFFEA020C52E37700002AA211A0E1A9\r
+S3150001C6B0813185E0086083E20C2095E52111A0E136\r
+S3150001C6C00130A0E3080096E5132182E10C2085E5FF\r
+S3150001C6D00C608EE508008EE50CE080E508E086E555\r
+S3150001C6E0C73FA0E1233F87E00CA095E50120A0E329\r
+S3150001C6F04331A0E11263A0E10A0056E10A20A0E15C\r
+S3150001C7003600008A0A0016E10800001A8660A0E1D8\r
+S3150001C7100330C7E30A0016E1047083E20300001A3E\r
+S3150001C7208660A0E1020016E1047087E2FBFFFF0AC2\r
+S3150001C730873185E0080083E20790A0E10010A0E1BF\r
+S3150001C7400CE091E501005EE10900000A04309EE576\r
+S3150001C7500120C3E302C064E00F005CE33D0000CAB0\r
+S3150001C76000005CE3320000AA0CE09EE501005EE1F8\r
+S3150001C770F5FFFF1A017087E2030017E3081081E253\r
+S3150001C780EEFFFF1A0620E0E1030019E302300A007A\r
+S3150001C790080040E2019049E203A0A0010C308505A2\r
+S3150001C7A00200000A083090E5000053E1F5FFFF0A98\r
+S3150001C7B08660A0E10A0056E10800008A000056E3FF\r
+S3150001C7C00600000A0A0016E1D8FFFF1A8660A0E1FA\r
+S3150001C7D00A0016E1047087E2FBFFFF0AD3FFFFEAB6\r
+S3150001C7E0101095E5042091E50120C2E302C064E042\r
+S3150001C7F00F005CE30030A0C30130A0D3040052E176\r
+S3150001C80001308333000053E301E0A00101208C03D2\r
+S3150001C810041081000130840304308E051010850553\r
+S3150001C8200420810508708E0278FFFF0A0070A0E3DC\r
+S3150001C83076FFFFEA02208EE0043092E50C609EE569\r
+S3150001C84008009EE5013083E308708EE2043082E53C\r
+S3150001C850080086E56CFFFFEA08009EE50C609EE590\r
+S3150001C86004108EE0012084E301308CE3080086E5A4\r
+S3150001C87004208EE5181085E508708EE20CC081E76C\r
+S3150001C880080181E90C6080E578FFFFEAA214B0E1B6\r
+S3150001C890A211A0011300000A040051E32233A09162\r
+S3150001C8A0381083920F00009A140051E35B108192B5\r
+S3150001C8B00C00009A540051E32236A0916E10839227\r
+S3150001C8C00800009A550F51E3A237A0917710839281\r
+S3150001C8D00400009A24319FE5030051E12239A09119\r
+S3150001C8E07C1083927E10A083813185E0086083E20B\r
+S3150001C8F0080096E5060050E10C00000A043090E5B8\r
+S3150001C9000130C3E3030052E10600002A080090E566\r
+S3150001C910060050E10300000A043090E50130C3E34C\r
+S3150001C920030052E1F8FFFF3A0C6090E567FFFFEA6A\r
+S3150001C9300C3095E52111A0E10120A0E3123183E13C\r
+S3150001C9400C3085E561FFFFEAA424B0E1A471A001E2\r
+S3150001C9501300000A040052E32433A0913870839235\r
+S3150001C9600F00009A140052E35B7082920C00009A49\r
+S3150001C970540052E32436A0916E7083920800009A07\r
+S3150001C980550F52E3A437A091777083920400009A61\r
+S3150001C99068309FE5030052E12439A0917C708392AF\r
+S3150001C9A07E70A083873185E0081083E20CE091E573\r
+S3150001C9B001005EE10900000A04309EE50120C3E39F\r
+S3150001C9C002C064E00F005CE30A0000CA00005CE3F9\r
+S3150001C9D0040000AA0CE09EE501005EE1F5FFFF1AE6\r
+S3150001C9E0017087E210FFFFEA02208EE0043092E533\r
+S3150001C9F00C609EE5FFFEFFEA017047E2F7FFFFEAE2\r
+S3150001CA0054050000000051E3F0412DE90070A0E15A\r
+S3150001CA100100A001F081BD08085041E204C095E57E\r
+S3150001CA20102090E50140CCE304E085E004309EE56A\r
+S3150001CA3002005EE10160C3E36900000A01302CE2F5\r
+S3150001CA40010013E304608EE50080A0E30900000AFB\r
+S3150001CA50081011E5103080E2055061E0082095E5E7\r
+S3150001CA60014084E0030052E10C0095150180880223\r
+S3150001CA70082080150C00821506208EE00430D2E5D0\r
+S3150001CA80013023E2010013E30A00000A000058E323\r
+S3150001CA90064084E008209E150300001A08209EE542\r
+S3150001CAA0103087E2030052E14700000A0C009EE5C0\r
+S3150001CAB0082080E50C0082E5013084E3000058E39C\r
+S3150001CAC0043085E5044085E70E00001A020C54E3A4\r
+S3150001CAD00E00002AA411A0E1813187E0080083E25B\r
+S3150001CAE00C2097E52111A0E10130A0E308C090E5F3\r
+S3150001CAF0132182E10C2087E50C0085E508C085E558\r
+S3150001CB000C508CE5085080E50100A0E3F081BDE8FA\r
+S3150001CB10A414B0E1A411A0011300000A040051E31A\r
+S3150001CB202433A091381083920F00009A140051E328\r
+S3150001CB305B1081920C00009A540051E32436A091B7\r
+S3150001CB406E1083920800009A550F51E3A437A09105\r
+S3150001CB50771083920400009AC4309FE5030051E1E7\r
+S3150001CB602439A0917C1083927E10A083813187E0C5\r
+S3150001CB70080083E208C090E500005CE10C00000AB1\r
+S3150001CB8004309CE50130C3E3030054E10600002AAA\r
+S3150001CB9008C09CE500005CE10300000A04309CE546\r
+S3150001CBA00130C3E3030054E1F8FFFF3A0C009CE5B2\r
+S3150001CBB0D0FFFFEA0C3097E52111A0E10120A0E3A7\r
+S3150001CBC0123183E10C3087E5CAFFFFEA0180A0E359\r
+S3150001CBD01C5087E5185087E50C2085E5082085E57A\r
+S3150001CBE0B4FFFFEA01302CE2010013E3064084E0C2\r
+S3150001CBF00600000A081011E5055061E00C0095E5F4\r
+S3150001CC0008C095E5014084E008C080E50C008CE58C\r
+S3150001CC10013084E30100A0E3105087E5043085E587\r
+S3150001CC20F081BDE8540500000DC0A0E1F0DF2DE95B\r
+S3150001CC30084041E20180A0E1041094E5000053E3BD\r
+S3150001CC400150C1E30B2082E204B04CE203C0A0E133\r
+S3150001CC500430451200308C15160052E30090A0E115\r
+S3150001CC600770C2C30500A0E11070A0D304E0A0E1E3\r
+S3150001CC70070050E108608EA2180000AA105099E53D\r
+S3150001CC8000C08EE005005CE1C400000A04109CE5CA\r
+S3150001CC900120C1E302208CE00430D2E5013023E219\r
+S3150001CCA0013013E203C0A0010360A0012800000ABD\r
+S3150001CCB005005CE10160C1E3A900000A001086E0FD\r
+S3150001CCC0070051E1220000BA08309CE50C209CE5E2\r
+S3150001CCD00150A0E108608EE2083082E50C2083E570\r
+S3150001CCE0050067E00F0050E30900008A043094E56F\r
+S3150001CCF0051084E0013003E2053083E1043084E568\r
+S3150001CD00042091E5012082E3042081E50600A0E1EB\r
+S3150001CD10F0AF1BE9043094E5071084E0013003E22B\r
+S3150001CD20073083E1012080E3043084E5000081E0DF\r
+S3150001CD30042081E5043090E5081081E2013083E3A7\r
+S3150001CD40043080E50020A0E30900A0E12CFFFFEB01\r
+S3150001CD50EDFFFFEA0430DEE5013023E2010013E3D3\r
+S3150001CD604200000A00209EE500005CE30EA062E09E\r
+S3150001CD7004309AE501E0C3E33600000A05005CE1F0\r
+S3150001CD803C00000A0E3086E0001083E0070051E106\r
+S3150001CD90300000BA08309CE50C209CE504C040E256\r
+S3150001CDA0083082E50C2083E50C209AE508309AE5E7\r
+S3150001CDB024005CE30A40A0E1083082E50C2083E50B\r
+S3150001CDC00150A0E108608AE21D00008A13005CE3BD\r
+S3150001CDD00800A0E10610A0E11200009A043090E4D8\r
+S3150001CDE01B005CE308308AE5042098E5040080E234\r
+S3150001CDF00C208AE510108AE20A00009A043090E4B9\r
+S3150001CE0023005CE310308AE5042090E418108AE2DE\r
+S3150001CE1014208AE50420908420108A8218208A85AD\r
+S3150001CE20043090841C308A85043090E4043081E417\r
+S3150001CE30042090E4042081E4003090E5003081E58F\r
+S3150001CE40A6FFFFEA0810A0E10C20A0E10600A0E180\r
+S3150001CE5064DAFFEBA1FFFFEA00005AE30300000AD0\r
+S3150001CE6000108EE0070051E104C040A2CDFFFFAAE9\r
+S3150001CE700000A0E3F0AF1BE90E3086E0006083E01E\r
+S3150001CE80102087E2020056E1F2FFFFBA0C209AE574\r
+S3150001CE9008309AE504C040E224005CE30A40A0E1C0\r
+S3150001CEA0083082E50C2083E508508AE22700008AD3\r
+S3150001CEB013005CE30800A0E10510A0E11200009A4E\r
+S3150001CEC0043090E41B005CE308308AE5042098E511\r
+S3150001CED0040080E20C208AE510108AE20A00009A1A\r
+S3150001CEE0043090E423005CE310308AE5042090E4EA\r
+S3150001CEF018108AE214208AE50420908420108A8280\r
+S3150001CF0018208A85043090841C308A85043090E488\r
+S3150001CF10043081E4042090E4042081E4003090E5AB\r
+S3150001CF20003081E5063067E007108AE0013083E3CF\r
+S3150001CF30043081E504209AE50500A0E1012002E222\r
+S3150001CF40072082E104208AE5101089E5F0AF1BE98C\r
+S3150001CF500810A0E10C20A0E10500A0E121DAFFEB19\r
+S3150001CF60EFFFFFEA002086E0103087E2030052E17E\r
+S3150001CF7077FFFFBA023067E007108EE0013083E3E6\r
+S3150001CF80043081E504209EE508008EE2012002E2DC\r
+S3150001CF90072082E1101089E504208EE5F0AF1BE938\r
+S3150001CFA004109CE541FFFFEA0118A0E1170711E310\r
+S3150001CFB0F0402DE90060A0E10250A0E14178A0E136\r
+S3150001CFC02200000A103090E57E40A0E3042093E59C\r
+S3150001CFD0100080E201E0C2E30F005EE30010A0D37F\r
+S3150001CFE00110A0C30E20A0E10CC090E500005CE199\r
+S3150001CFF00800000A04309CE50CC09CE50130C3E33F\r
+S3150001D000030052E10320A0B100005CE103E08EE0E1\r
+S3150001D010011081E2F6FFFF1A014054E2080080E2A6\r
+S3150001D020F0FFFF5A080017E3043096150720C2E304\r
+S3150001D03003306E100C3085150730CEE3143043E211\r
+S3150001D040142042E2103085E5081085E5182085E5B3\r
+S3150001D050003096E5003085E5203085E5042096E52B\r
+S3150001D0601830A0E32830C5E5042085E5242085E5B0\r
+S3150001D070F080BDE818109FE50030A0E30120A0E391\r
+S3150001D080032181E7013083E2110053E30EF0A08111\r
+S3150001D090FAFFFFEA1CB0020018109FE50030A0E37A\r
+S3150001D0A00120A0E3032181E7013083E2110053E36C\r
+S3150001D0B00EF0A081FAFFFFEA1CB002000DC0A0E14C\r
+S3150001D0C000D82DE9FA0F80E204B04CE2300000EB03\r
+S3150001D0D004E02DE504009FE504E09DE4B2E7FFEAE4\r
+S3150001D0E064B0020004E02DE504009FE504E09DE440\r
+S3150001D0F03CE8FFEA64B002000DC0A0E170D82DE95A\r
+S3150001D10050609FE50050A0E1060051E10100500387\r
+S3150001D11004B04CE20140A0E13C009FE50B00000A8F\r
+S3150001D120060054E10100550330009FE50500000AA1\r
+S3150001D130060054E1000055031C009FE570A81B1969\r
+S3150001D14070681BE994E7FFEAD2FFFFEBF7FFFFEAFE\r
+S3150001D15078E7FFEBF1FFFFEA20CB000064B00200A5\r
+S3150001D16078B0020004E02DE508109FE50100A0E378\r
+S3150001D17004E09DE4DFFFFFEA20CB000004E02DE59B\r
+S3150001D18008109FE50000A0E304E09DE4D9FFFFEA53\r
+S3150001D19020CB00000DC0A0E110D82DE904B04CE26F\r
+S3150001D1A00040A0E1720000EB0000A0E34D0000EB9F\r
+S3150001D1B00400A0E1690000EB0DC0A0E130D82DE923\r
+S3150001D1C01C309FE504B04CE2300093E814104BE2AA\r
+S3150001D1D008D04DE20100A0E3300021E9E5ABFFEB09\r
+S3150001D1E0EBFFFFEBE41202000DC0A0E1F0DF2DE939\r
+S3150001D1F004B04CE224D04DE20090A0E12020A0E34F\r
+S3150001D20048004BE20010A0E30080A0E3A5D9FFEBA4\r
+S3150001D2104C800BE500A0A0E3000058E30A50A0E112\r
+S3150001D2201F00001A28604BE2203016E5000053E388\r
+S3150001D2301600001AA8309FE5054193E7090054E15D\r
+S3150001D240000054130F00000A2430D4E5800013E3D4\r
+S3150001D2500E00001A4C301BE5000053E32C708402CB\r
+S3150001D2601900001A0700A0E1B3E7FFEB000050E345\r
+S3150001D2701200000A0400A0E154EEFFEB0080A0E1D9\r
+S3150001D2800700A0E1D7E7FFEB0130A0E3203006E578\r
+S3150001D290015085E2070055E300005893046086E2D9\r
+S3150001D2A0E0FFFF0A000058E30030A01301300A0234\r
+S3150001D2B0000053E30800A001F0AF1B09D4FFFFEA09\r
+S3150001D2C001A0A0E34CA00BE5F0FFFFEA2C7084E27D\r
+S3150001D2D00700A0E134E7FFEB000050E3E4FFFF1A8B\r
+S3150001D2E0DFFFFFEA042102000DC0A0E1000050E3C8\r
+S3150001D2F030D82DE904B04CE20040A0E12C5080E288\r
+S3150001D3001300000A0500A0E127E7FFEB0030A0E1CA\r
+S3150001D310000053E30400A0E10940A0E30700001A5E\r
+S3150001D320000054E30430A0E10200000AF2F6FFEB2C\r
+S3150001D3300030E0E3004080E50300A0E130A81BE9EE\r
+S3150001D34022EEFFEB0040A0E10500A0E1A5E7FFEB1F\r
+S3150001D350F2FFFFEAA3FFFFEB0040A0E1EFFFFFEAC8\r
+S3150001D3600DC0A0E100D82DE904B04CE2D4DEFFEBFC\r
+S3150001D370FEFFFFEA0DC0A0E130D82DE928309FE578\r
+S3150001D38004B04CE2004093E5000054E330A81B09C9\r
+S3150001D39018309FE5045183E00FE0A0E104F035E584\r
+S3150001D3A0014054E230A81B09FAFFFFEAFCB0020073\r
+S3150001D3B07CB0020024C09FE50130A0E300209CE57B\r
+S3150001D3C01F0052E3031082E014309F9500108C95E4\r
+S3150001D3D0020183970030A0930300A0E10EF0A0E1C3\r
+S3150001D3E0FCB002007CB00200000051E31F00000AFD\r
+S3150001D3F00130A0E30020A0E3010050E11900003A4A\r
+S3150001D400010251E3000051310112A0310332A03172\r
+S3150001D410FAFFFF3A020151E3000051318110A031B8\r
+S3150001D4208330A031FAFFFF3A010050E101004020AC\r
+S3150001D43003208221A10050E1A1004020A3208221E6\r
+S3150001D440210150E12101402023218221A10150E146\r
+S3150001D450A1014020A3218221000050E32332B01113\r
+S3150001D4602112A011EFFFFF1A0200A0E10EF0A0E1C8\r
+S3150001D47004E02DE5620000EB0000A0E30080BDE8BA\r
+S3150001D48001C020E00130A0E30020A0E3000051E349\r
+S3150001D490001061422100000A000050E300006042D2\r
+S3150001D4A0010050E11900003A010251E30000513137\r
+S3150001D4B00112A0310332A031FAFFFF3A020151E312\r
+S3150001D4C0000051318110A0318330A031FAFFFF3ABB\r
+S3150001D4D0010050E10100402003208221A10050E11A\r
+S3150001D4E0A1004020A3208221210150E121014020F9\r
+S3150001D4F023218221A10150E1A1014020A321822102\r
+S3150001D500000050E32332B0112112A011EFFFFF1AE0\r
+S3150001D5100200A0E100005CE3000060420EF0A0E121\r
+S3150001D52004E02DE5360000EB0000A0E30080BDE835\r
+S3150001D530000051E3001061422D00000A04002DE5B0\r
+S3150001D540000050E300006042010050E12400003A6F\r
+S3150001D5500130A0E3010251E3000051310112A03173\r
+S3150001D5600332A031FAFFFF3A020151E300005131C3\r
+S3150001D5708110A0318330A031FAFFFF3A0020A0E3E9\r
+S3150001D580010050E101004020A10050E1A10040202E\r
+S3150001D590E3208221210150E12101402063218221E2\r
+S3150001D5A0A10150E1A1014020E321822103C0A0E1B4\r
+S3150001D5B0000050E32332B0112112A011EEFFFF1A31\r
+S3150001D5C00E2212E207001C130500000AEC0112E10B\r
+S3150001D5D0A10180106C0112E121018010EC0012E121\r
+S3150001D5E0A100801004C09DE400005CE300006042DD\r
+S3150001D5F00EF0A0E104E02DE5010000EB0000A0E340\r
+S3150001D6000080BDE80EF0A0E1000052E370402DE974\r
+S3150001D61020C062E20140A0E10030A0E10060A0E389\r
+S3150001D6200050A0E30800000A00005CE33032A0E1EC\r
+S3150001D63000E06CE2C16FA0D1515EA0D15162A0C1E0\r
+S3150001D640115C83C10640A0E10530A0E10410A0E110\r
+S3150001D6500300A0E17080BDE80DC0A0E130D82DE93E\r
+S3150001D6604C208FE20C0092E804B04CE20150A0E19C\r
+S3150001D6700040A0E19E0600EB00C0A0E100005CE3D3\r
+S3150001D6800510A0E10400A0E12C208FE20C0092E835\r
+S3150001D690030000BA040400EB130700EB020180E269\r
+S3150001D6A030A81BE90510A0E10400A0E10E0700EB7C\r
+S3150001D6B030A81BE90000E041000000000000E0C1C5\r
+S3150001D6C0000000000DC0A0E100D82DE904B04CE235\r
+S3150001D6D004D04DE200C0A0E300C08DE5000000EBE0\r
+S3150001D6E000A81BE90DC0A0E1F0DF2DE904B04CE272\r
+S3150001D6F00060A0E30050A0E330C04BE230D04DE221\r
+S3150001D700004053E20090A0E160008CE860000CE963\r
+S3150001D7100260A0E10150A0E1DE00001A010052E121\r
+S3150001D7205600009A010852E30210A0E14F00002AB8\r
+S3150001D730FF0052E30800A0830000A093D0259FE5D7\r
+S3150001D7403110A0E10130D2E7003083E0203073E2EE\r
+S3150001D75040300BE50500000A40101BE5203063E26E\r
+S3150001D7603933A0E1155183E11661A0E11991A0E1D8\r
+S3150001D7702678A0E1FF3CA0E3FF3083E20710A0E199\r
+S3150001D7800500A0E103A006E02A0700EB0710A0E1CF\r
+S3150001D7900040A0E10500A0E112FFFFEB9A0001E0C5\r
+S3150001D7A02938A0E1044883E1010054E10080A0E1A9\r
+S3150001D7B00500002A064094E0018040E20200002AAA\r
+S3150001D7C0010054E10180483206408430044061E0A2\r
+S3150001D7D00400A0E10710A0E1160700EB0710A0E185\r
+S3150001D7E00050A0E10400A0E1FEFEFFEB9A0001E07B\r
+S3150001D7F0FF3CA0E3FF3083E2033009E0055883E1F3\r
+S3150001D800010055E10500002A065095E0010040E2BD\r
+S3150001D8100200002A010055E1065085300100403220\r
+S3150001D82008C880E1059061E000A0A0E304509BE5F3\r
+S3150001D830000055E30800000A40601BE50010A0E364\r
+S3150001D8403996A0E138900BE534100BE530204BE218\r
+S3150001D8500C0012E90540A0E10C0084E830C00BE59C\r
+S3150001D8602CA00BE530404BE2030094E8F0AF1BE936\r
+S3150001D870010452E31800A0231000A033AEFFFFEA13\r
+S3150001D880000052E30300001A0210A0E10100A0E328\r
+S3150001D890D4FEFFEB0060A0E1010856E37900002AFF\r
+S3150001D8A0FF0056E30800A0830000A09360249FE5D3\r
+S3150001D8B03610A0E10130D2E7003083E0203073E278\r
+S3150001D8C040300BE50550660001A0A0032688A001A3\r
+S3150001D8D03B00000A40301BE540201BE51663A0E132\r
+S3150001D8E0202062E2FF3CA0E335A2A0E12688A0E168\r
+S3150001D8F040401BE5FF3083E2033006E03C200BE5A8\r
+S3150001D9000A00A0E13922A0E10810A0E1155482E144\r
+S3150001D91048300BE5C70600EB0810A0E10070A0E156\r
+S3150001D9200A00A0E1AFFEFFEB48201BE5900202E0F2\r
+S3150001D9302538A0E1077883E1020057E100A0A0E1C4\r
+S3150001D9401994A0E144800BE50500002A067097E0D2\r
+S3150001D95001A040E20200002A020057E101A04A327A\r
+S3150001D96006708730077062E044101BE50700A0E1EE\r
+S3150001D970B00600EB44101BE50040A0E10700A0E162\r
+S3150001D98098FEFFEB48201BE5900202E0FF3CA0E376\r
+S3150001D990FF3083E2033005E0044883E1020054E1ED\r
+S3150001D9A00500002A064094E0010040E20200002A38\r
+S3150001D9B0020054E101004032064084300AA880E1A9\r
+S3150001D9C0045062E0FF3CA0E3FF3083E2033006E04F\r
+S3150001D9D00810A0E10500A0E14C300BE5950600EB2F\r
+S3150001D9E00810A0E10040A0E10500A0E17DFEFFEBEB\r
+S3150001D9F04C101BE5900101E02938A0E1044883E1C0\r
+S3150001DA00010054E10070A0E10500002A064094E0FF\r
+S3150001DA10017040E20200002A010054E10170473220\r
+S3150001DA2006408430044061E00400A0E10810A0E152\r
+S3150001DA30800600EB0810A0E10050A0E10400A0E17F\r
+S3150001DA4068FEFFEB4C101BE5900101E0FF3CA0E3F3\r
+S3150001DA50FF3083E2033009E0055883E1010055E117\r
+S3150001DA600500002A065095E0010040E20200002A66\r
+S3150001DA70010055E1065085300100403207C880E1BA\r
+S3150001DA80059061E068FFFFEA010456E31800A02350\r
+S3150001DA901000A03384FFFFEA010054E10B00009A55\r
+S3150001DAA004309BE500A0A0E3000053E30AC0A0E117\r
+S3150001DAB069FFFF0A38000BE534100BE530404BE2F5\r
+S3150001DAC0300014E90360A0E1300083E862FFFFEA59\r
+S3150001DAD0010854E38A00002AFF0054E30800A083EA\r
+S3150001DAE00000A09328229FE53410A0E10130D2E77F\r
+S3150001DAF0003083E0203073E240300BE51100001A5C\r
+S3150001DB00040055E10600599140C01B350300003A57\r
+S3150001DB1006C059E00450C5E00C90A0E101C0A0E3A5\r
+S3150001DB2004109BE5000051E300A0A0E34AFFFF0AB1\r
+S3150001DB3038900BE534500BE530204BE20C0012E92E\r
+S3150001DB400140A0E143FFFFEA40301BE540C01BE571\r
+S3150001DB50203063E23C300BE53633A0E1144C83E11F\r
+S3150001DB603C101BE52428A0E1FF3CA0E335A1A0E180\r
+S3150001DB7050200BE5FF3083E23921A0E1033004E0B8\r
+S3150001DB800A00A0E150101BE5155C82E154300BE55B\r
+S3150001DB90280600EB50101BE50080A0E10A00A0E179\r
+S3150001DBA010FEFFEB54301BE500A0A0E1930A0AE04A\r
+S3150001DBB02538A0E140C01BE5088883E10A0058E149\r
+S3150001DBC058000BE5166CA0E1199CA0E10700002A9C\r
+S3150001DBD0011040E2048098E058100BE50300002A8A\r
+S3150001DBE00A0058E10110413258100B350480883083\r
+S3150001DBF008806AE050101BE50800A0E10D0600EB65\r
+S3150001DC0050101BE50070A0E10800A0E1F5FDFFEB57\r
+S3150001DC1054A01BE5900A0AE0FF3CA0E3FF3083E233\r
+S3150001DC20033005E0077883E10A0057E10500002A81\r
+S3150001DC30047097E0010040E20200002A0A0057E161\r
+S3150001DC40010040320470873058201BE507706AE0F6\r
+S3150001DC5002C880E12C18A0E12608A0E10128CCE148\r
+S3150001DC600038C6E192030EE0910303E0900202E060\r
+S3150001DC70910000E0022093E00108802202E89EE084\r
+S3150001DC802208A0E0070050E10600008A0030A01338\r
+S3150001DC900130A00309005EE10030A0930130038248\r
+S3150001DCA0000053E30300000A06305EE00400C0E012\r
+S3150001DCB003E0A0E101C04CE204409BE5000054E30F\r
+S3150001DCC000A0A0E3E4FEFF0A40101BE50E6059E048\r
+S3150001DCD00050C7E03C201BE53631A0E1153283E157\r
+S3150001DCE03551A0E138300BE534500BE530304BE2CD\r
+S3150001DCF0180013E904509BE5180085E80690A0E199\r
+S3150001DD00D5FEFFEA010454E31800A0231000A03356\r
+S3150001DD1073FFFFEA001302000DC0A0E100D82DE950\r
+S3150001DD2004B04CE20CD04DE214C04BE200C08DE5CC\r
+S3150001DD30020000EB10304BE2030013E800A81BE9D8\r
+S3150001DD400DC0A0E1F0DF2DE904B04CE20060A0E3D4\r
+S3150001DD500050A0E330C04BE230D04DE2004053E228\r
+S3150001DD600090A0E160008CE860000CE90260A0E18F\r
+S3150001DD700150A0E1DE00001A010052E15600009AAE\r
+S3150001DD80010852E30210A0E14F00002AFF0052E30E\r
+S3150001DD900800A0830000A093D0259FE53110A0E1E3\r
+S3150001DDA00130D2E7003083E0203073E240300BE5EA\r
+S3150001DDB00500000A40101BE5203063E23933A0E17B\r
+S3150001DDC0155183E11661A0E11991A0E12678A0E140\r
+S3150001DDD0FF3CA0E3FF3083E20710A0E10500A0E1CC\r
+S3150001DDE003A006E0930500EB0710A0E10040A0E1C7\r
+S3150001DDF00500A0E17BFDFFEB9A0001E02938A0E1D7\r
+S3150001DE00044883E1010054E10080A0E10500002AF5\r
+S3150001DE10064094E0018040E20200002A010054E13C\r
+S3150001DE200180483206408430044061E00400A0E1EC\r
+S3150001DE300710A0E17F0500EB0710A0E10050A0E16B\r
+S3150001DE400400A0E167FDFFEB9A0001E0FF3CA0E3BF\r
+S3150001DE50FF3083E2033009E0055883E1010055E113\r
+S3150001DE600500002A065095E0010040E20200002A62\r
+S3150001DE70010055E1065085300100403208C880E1B5\r
+S3150001DE80059061E000A0A0E304509BE5000055E386\r
+S3150001DE900800000A40601BE50010A0E33996A0E1E6\r
+S3150001DEA038900BE534100BE530204BE20C0012E9FB\r
+S3150001DEB00540A0E10C0084E830C00BE52CA00BE581\r
+S3150001DEC030404BE2030094E8F0AF1BE9010452E352\r
+S3150001DED01800A0231000A033AEFFFFEA000052E3B2\r
+S3150001DEE00300001A0210A0E10100A0E33DFDFFEBD3\r
+S3150001DEF00060A0E1010856E37900002AFF0056E31D\r
+S3150001DF000800A0830000A09360249FE53610A0E1DD\r
+S3150001DF100130D2E7003083E0203073E240300BE578\r
+S3150001DF200550660001A0A0032688A0013B00000A57\r
+S3150001DF3040301BE540201BE51663A0E1202062E28C\r
+S3150001DF40FF3CA0E335A2A0E12688A0E140401BE505\r
+S3150001DF50FF3083E2033006E03C200BE50A00A0E136\r
+S3150001DF603922A0E10810A0E1155482E148300BE501\r
+S3150001DF70300500EB0810A0E10070A0E10A00A0E165\r
+S3150001DF8018FDFFEB48201BE5900202E02538A0E1D1\r
+S3150001DF90077883E1020057E100A0A0E11994A0E10E\r
+S3150001DFA044800BE50500002A067097E001A040E2D7\r
+S3150001DFB00200002A020057E101A04A3206708730AA\r
+S3150001DFC0077062E044101BE50700A0E1190500EBAC\r
+S3150001DFD044101BE50040A0E10700A0E101FDFFEBB5\r
+S3150001DFE048201BE5900202E0FF3CA0E3FF3083E2FC\r
+S3150001DFF0033005E0044883E1020054E10500002AEC\r
+S3150001E000064094E0010040E20200002A020054E1C9\r
+S3150001E01001004032064084300AA880E1045062E0E3\r
+S3150001E020FF3CA0E3FF3083E2033006E00810A0E1E5\r
+S3150001E0300500A0E14C300BE5FE0400EB0810A0E161\r
+S3150001E0400040A0E10500A0E1E6FCFFEB4C101BE55A\r
+S3150001E050900101E02938A0E1044883E1010054E17F\r
+S3150001E0600070A0E10500002A064094E0017040E23C\r
+S3150001E0700200002A010054E1017047320640843053\r
+S3150001E080044061E00400A0E10810A0E1E90400EB0E\r
+S3150001E0900810A0E10050A0E10400A0E1D1FCFFEBD3\r
+S3150001E0A04C101BE5900101E0FF3CA0E3FF3083E249\r
+S3150001E0B0033009E0055883E1010055E10500002A16\r
+S3150001E0C0065095E0010040E20200002A010055E1F8\r
+S3150001E0D0065085300100403207C880E1059061E0B5\r
+S3150001E0E068FFFFEA010456E31800A0231000A033DD\r
+S3150001E0F084FFFFEA010054E10B00009A04309BE51E\r
+S3150001E10000A0A0E3000053E30AC0A0E169FFFF0AF3\r
+S3150001E11038000BE534100BE530404BE2300014E9D2\r
+S3150001E1200360A0E1300083E862FFFFEA010854E3DF\r
+S3150001E1308A00002AFF0054E30800A0830000A09390\r
+S3150001E14028229FE53410A0E10130D2E7003083E0B8\r
+S3150001E150203073E240300BE51100001A040055E14E\r
+S3150001E1600600599140C01B350300003A06C059E02C\r
+S3150001E1700450C5E00C90A0E101C0A0E304109BE5AA\r
+S3150001E180000051E300A0A0E34AFFFF0A38900BE527\r
+S3150001E19034500BE530204BE20C0012E90140A0E1BE\r
+S3150001E1A043FFFFEA40301BE540C01BE5203063E238\r
+S3150001E1B03C300BE53633A0E1144C83E13C101BE502\r
+S3150001E1C02428A0E1FF3CA0E335A1A0E150200BE506\r
+S3150001E1D0FF3083E23921A0E1033004E00A00A0E127\r
+S3150001E1E050101BE5155C82E154300BE5910400EB00\r
+S3150001E1F050101BE50080A0E10A00A0E179FCFFEBCD\r
+S3150001E20054301BE500A0A0E1930A0AE02538A0E1FD\r
+S3150001E21040C01BE5088883E10A0058E158000BE578\r
+S3150001E220166CA0E1199CA0E10700002A011040E24A\r
+S3150001E230048098E058100BE50300002A0A0058E113\r
+S3150001E2400110413258100B350480883008806AE08D\r
+S3150001E25050101BE50800A0E1760400EB50101BE509\r
+S3150001E2600070A0E10800A0E15EFCFFEB54A01BE5F5\r
+S3150001E270900A0AE0FF3CA0E3FF3083E2033005E0A9\r
+S3150001E280077883E10A0057E10500002A047097E048\r
+S3150001E290010040E20200002A0A0057E10100403273\r
+S3150001E2A00470873058201BE507706AE002C880E1D8\r
+S3150001E2B02C18A0E12608A0E10128CCE10038C6E12E\r
+S3150001E2C092030EE0910303E0900202E0910000E068\r
+S3150001E2D0022093E00108802202E89EE02208A0E0E5\r
+S3150001E2E0070050E10600008A0030A0130130A003A8\r
+S3150001E2F009005EE10030A09301300382000053E380\r
+S3150001E3000300000A06305EE00400C0E003E0A0E17D\r
+S3150001E31001C04CE204409BE5000054E300A0A0E3E9\r
+S3150001E320E4FEFF0A40101BE50E6059E00050C7E00D\r
+S3150001E3303C201BE53631A0E1153283E13551A0E1E0\r
+S3150001E34038300BE534500BE530304BE2180013E959\r
+S3150001E35004509BE5180085E80690A0E1D5FEFFEA8A\r
+S3150001E360010454E31800A0231000A03373FFFFEA51\r
+S3150001E370001302000DC0A0E1F0DF2DE904B04CE26C\r
+S3150001E38010D04DE20170A0E10280A0E10060A0E1A1\r
+S3150001E390FB0000EB000050E30100000A0600A0E1CB\r
+S3150001E3A0F0AF1BE90700A0E1F50000EB000050E328\r
+S3150001E3B00100000A0700A0E1F0AF1BE90600A0E199\r
+S3150001E3C0F40000EB000050E30900000A0700A0E199\r
+S3150001E3D0F00000EB000050E3EFFFFF0A042097E591\r
+S3150001E3E0043096E5020053E1EBFFFF0AF06F1BE9EB\r
+S3150001E3F0E00000EA0700A0E1E60000EB000050E3C0\r
+S3150001E400EBFFFF1A0700A0E1E70000EB000050E375\r
+S3150001E4100F00000A0600A0E1E30000EB000050E354\r
+S3150001E420DDFFFF0A06E0A0E10F00BEE808C0A0E19B\r
+S3150001E4300F00ACE800309EE500308CE5042096E53F\r
+S3150001E440043097E50800A0E1032002E0042088E5F6\r
+S3150001E450F0AF1BE90600A0E1D30000EB000050E39A\r
+S3150001E460D3FFFF1A0C2086E208E096E508C097E57F\r
+S3150001E470030092E830404BE20E306CE0030084E882\r
+S3150001E480000053E3003063B23F0053E30C3087E2F0\r
+S3150001E490000693E87A0000CA0C005EE10C0000DA7F\r
+S3150001E4A00EC06CE00010A0E30100A0E3A930A0E1DA\r
+S3150001E4B001500AE0004009E08A1F83E1AA20A0E199\r
+S3150001E4C001C05CE2019084E102A085E1F4FFFF1A3C\r
+S3150001E4D00EC0A0E10E005CE1140000DA30404BE210\r
+S3150001E4E00C0094E80050A0E30140A0E3042002E000\r
+S3150001E4F0053003E030504BE20C0005E930104BE2E9\r
+S3150001E500220091E8A100A0E130204BE2853F80E1A5\r
+S3150001E510030012E901E08EE2A540A0E1030080E1DB\r
+S3150001E520041081E10E005CE1030082E8EAFFFFCA04\r
+S3150001E530040096E5043097E5030050E14800000A1F\r
+S3150001E540000050E34100000A30204BE2030092E84C\r
+S3150001E550000059E00110CAE0000051E3340000BA9E\r
+S3150001E5600C7088E20030A0E3084088E9030087E8E0\r
+S3150001E570060097E80040E0E30030E0E3031091E095\r
+S3150001E5800420A2E01F0272E31100008A2500000A9E\r
+S3150001E590180097E88420A0E1A34F82E10010E0E390\r
+S3150001E5A00000E0E38330A0E1082098E5030090E055\r
+S3150001E5B00410A1E0012042E21F0271E3082088E570\r
+S3150001E5C0180087E80200008AF0FFFF1A020070E3D4\r
+S3150001E5D0EEFFFF9A043097E50320A0E31E0273E3E2\r
+S3150001E5E0002088E50D00009A060097E80040A0E3A8\r
+S3150001E5F00130A0E3A1C0A0E1035001E0046002E004\r
+S3150001E600080098E5823F8CE1A240A0E1031085E174\r
+S3150001E610042086E1010080E2060087E8080088E51B\r
+S3150001E6200800A0E1F0AF1BE9020071E3D7FFFF9AF2\r
+S3150001E630E7FFFFEA003070E20040E1E20C7088E299\r
+S3150001E6400120A0E3180087E8044088E9C7FFFFEA34\r
+S3150001E65030304BE2030093E8090050E00A10C1E0B4\r
+S3150001E660BCFFFFEA30104BE2300091E8094094E02C\r
+S3150001E6700A50A5E00C7088E2300087E8014088E97D\r
+S3150001E680D3FFFFEA0C005EE100A0A0C30090A0C387\r
+S3150001E690A6FFFFCA0040A0E30030A0E330504BE2E2\r
+S3150001E6A0180085E80CE0A0E1A0FFFFEA0DC0A0E19B\r
+S3150001E6B0F0D92DE904B04CE264C04BE234804BE260\r
+S3150001E6C04CD04DE20150A0E10040A0E16C604BE26C\r
+S3150001E6D00C00A0E10810A0E148704BE230008CE884\r
+S3150001E6E00C0086E83C0400EB0600A0E10710A0E15F\r
+S3150001E6F0390400EB0710A0E15C204BE20800A0E121\r
+S3150001E7001BFFFFEB8F0300EBF0A91BE90DC0A0E196\r
+S3150001E710F0D92DE904B04CE264C04BE234804BE2FF\r
+S3150001E7204CD04DE20150A0E10040A0E16C604BE20B\r
+S3150001E7300C00A0E10810A0E148704BE230008CE823\r
+S3150001E7400C0086E8240400EB0600A0E10710A0E116\r
+S3150001E750210400EB44301BE50710A0E1013023E260\r
+S3150001E7605C204BE20800A0E144300BE500FFFFEB23\r
+S3150001E770740300EBF0A91BE900009FE50EF0A0E190\r
+S3150001E780EC120200000090E5010050E30000A083B6\r
+S3150001E7900100A0930EF0A0E1000090E5040050E313\r
+S3150001E7A00000A0130100A0030EF0A0E1000090E517\r
+S3150001E7B0020050E30000A0130100A0030EF0A0E147\r
+S3150001E7C00DC0A0E1F0D92DE904B04CE264C04BE2E2\r
+S3150001E7D034804BE24CD04DE20150A0E10040A0E173\r
+S3150001E7E06C604BE20C00A0E10810A0E148704BE21E\r
+S3150001E7F030008CE80C0086E8F70300EB0600A0E188\r
+S3150001E8000710A0E1F40300EB0710A0E15C204BE246\r
+S3150001E8100800A0E1010000EB4A0300EBF0A91BE9A7\r
+S3150001E8200DC0A0E1F0DF2DE904B04CE248D04DE285\r
+S3150001E8300160A0E10240A0E10050A0E1E50000EB8B\r
+S3150001E840000050E300A0A0E30090A0E30600000A48\r
+S3150001E850042096E5043095E50500A0E1023053E079\r
+S3150001E8600130A013043085E5F0AF1BE90600A0E1F5\r
+S3150001E870D80000EB000050E30600000A043095E5DD\r
+S3150001E880042096E50600A0E1023053E00130A01312\r
+S3150001E890043086E5F0AF1BE90500A0E1D20000EBEC\r
+S3150001E8A0000050E30500000A0600A0E1D30000EBDA\r
+S3150001E8B0000050E3E5FFFF0AF06F1BE9C20000EA22\r
+S3150001E8C00600A0E1C80000EB000050E30400000AC6\r
+S3150001E8D00500A0E1C90000EB000050E3E6FFFF0AD6\r
+S3150001E8E0F4FFFFEA0500A0E1C40000EB000050E3DD\r
+S3150001E8F0D6FFFF1A0600A0E1C00000EB000050E3BE\r
+S3150001E90034000BE5DCFFFF1A0C3086E2060093E8C3\r
+S3150001E9100CE095E50210A0E1912E83E040704BE2F8\r
+S3150001E9200C0007E80C0085E20C0090E80370A0E1FA\r
+S3150001E9300CC096E540004BE268700BE5800110E8DB\r
+S3150001E94068001BE5907CA8E040201BE5080052E129\r
+S3150001E950912083E050004BE250104BE2000601E8A3\r
+S3150001E9600C0080E99C9E8AE00300008A0600001ADA\r
+S3150001E97044201BE5070052E10300009A8E0F8FE247\r
+S3150001E980030090E850204BE2030002E80710A0E1E3\r
+S3150001E9900020A0E30030A0E340100BE544300BE576\r
+S3150001E9A040004BE2030010E8090090E00A10A1E0E4\r
+S3150001E9B060204BE201005AE1030082E90200008A6D\r
+S3150001E9C00800001A000059E10600009A50C04BE207\r
+S3150001E9D000061CE80020A0E30110A0E3019099E0E5\r
+S3150001E9E002A0AAE000060CE80800A0E10010A0E3DE\r
+S3150001E9F050804BE201A0A0E10090A0E1800198E9DE\r
+S3150001EA00080096E5041096E550604BE2082095E56E\r
+S3150001EA10043095E5600016E8079099E008A0AAE0A1\r
+S3150001EA2060704BE2059099E006A0AAE0002082E022\r
+S3150001EA30800197E9013053E00130A013042082E2FE\r
+S3150001EA4030C04BE21E027AE3043084E5082084E5F7\r
+S3150001EA5080018CE81B00009A0080A0E30170A0E30E\r
+S3150001EA60A920A0E130101BE58A2F82E1AAC0A0E10E\r
+S3150001EA70080094E564200BE560C00BE5A120A0E148\r
+S3150001EA802C301BE5071009E060C04BE2010080E273\r
+S3150001EA90000051E3835F82E1A360A0E100061CE868\r
+S3150001EAA0080084E50500000A452F8FE20C0092E874\r
+S3150001EAB0031086E1020085E130304BE2030083E872\r
+S3150001EAC01E027AE3E5FFFF8A1F027AE31F00008A2E\r
+S3150001EAD030304BE2880093E887C0A0E1A3CF8CE1F8\r
+S3150001EAE030204BE2800192E86CC00BE5D0108FE23A\r
+S3150001EAF0060091E883C0A0E170C00BE5080094E52B\r
+S3150001EB00017007E070104BE28A30A0E1028008E054\r
+S3150001EB10060091E8A96F83E1010040E28950A0E176\r
+S3150001EB2030304BE2087097E1060083E8080084E57F\r
+S3150001EB3006A0A0E10590A0E10030A0130120A013DA\r
+S3150001EB400290891103A08A111F027AE3DFFFFF9A5F\r
+S3150001EB50FF2009E20030A0E3800052E30500000A2D\r
+S3150001EB600C3084E20320A0E30400A0E1000683E860\r
+S3150001EB70002084E5F0AF1BE9000053E3F7FFFF1A1D\r
+S3150001EB800020A0E3011CA0E3091001E00A2002E035\r
+S3150001EB90021091E10300001A30304BE2280093E89D\r
+S3150001EBA0053093E1EDFFFF0A0020A0E38010A0E30A\r
+S3150001EBB0019099E002A0AAE0E8FFFFEA0000000048\r
+S3150001EBC001000000000000000000008000009FE539\r
+S3150001EBD00EF0A0E1EC120200000090E5010050E306\r
+S3150001EBE00000A0830100A0930EF0A0E1000090E5D3\r
+S3150001EBF0040050E30000A0130100A0030EF0A0E101\r
+S3150001EC00000090E5020050E30000A0130100A003FC\r
+S3150001EC100EF0A0E10DC0A0E1F0D92DE904B04CE25F\r
+S3150001EC2050C04BE234804BE238D04DE20150A0E1B6\r
+S3150001EC300040A0E158604BE20C00A0E10810A0E101\r
+S3150001EC4048704BE230008CE80C0086E8E20200EBEB\r
+S3150001EC500600A0E10710A0E1DF0200EB0710A0E12A\r
+S3150001EC600800A0E1010000EB360200EBF0A91BE968\r
+S3150001EC700DC0A0E1F0DB2DE904B04CE220D04DE25D\r
+S3150001EC800140A0E10050A0E1950000EB000050E337\r
+S3150001EC900100000A0500A0E1F0AB1BE90400A0E1B8\r
+S3150001ECA08F0000EB000050E30400A011F0AB1B192C\r
+S3150001ECB0043095E5042094E5023023E0043085E52F\r
+S3150001ECC00500A0E18B0000EB000050E30500000AFF\r
+S3150001ECD0002094E5003095E5020053E1ECFFFF1AB0\r
+S3150001ECE0F06B1BE97B0000EA0500A0E1860000EB62\r
+S3150001ECF0000050E30060A0E1F4FFFF1A0400A0E168\r
+S3150001ED007C0000EB000050E30600000A0C3085E2AF\r
+S3150001ED100020A0E30010A0E30500A0E1060083E8BF\r
+S3150001ED20086085E5F0AB1BE90400A0E1760000EB85\r
+S3150001ED30000050E30430A0130500A0110030851532\r
+S3150001ED40F0AB1B190C3084E2030093E830204BE250\r
+S3150001ED50030002E80CC085E2082095E5083094E539\r
+S3150001ED6000039CE8020063E0090051E1080085E523\r
+S3150001ED700300008A0900001A34301BE5080053E13C\r
+S3150001ED800600009A013040E28900A0E1A82F80E147\r
+S3150001ED908810A0E1083085E50290A0E10180A0E19C\r
+S3150001EDA04A0F8FE2030090E830204BE2030082E92C\r
+S3150001EDB00040A0E30030A0E340004BE2180080E9E8\r
+S3150001EDC02C104BE2120091E830201BE5A130A0E1A6\r
+S3150001EDD0843F83E1A400A0E1090052E144300BE540\r
+S3150001EDE040000BE50F00008A0200001A34101BE5F3\r
+S3150001EDF0080051E10B00008A30304BE20C0013E8A9\r
+S3150001EE00028058E00390C9E040204BE230304BE2EB\r
+S3150001EE10030092E90C0093E9031081E1020080E10D\r
+S3150001EE2040304BE2030083E940004BE2030010E867\r
+S3150001EE308930A0E130204BE2030082E9A87F83E11B\r
+S3150001EE408860A0E1011090E10790A0E10680A0E1B1\r
+S3150001EE50DAFFFF1A3C305BE50040A0E3800053E394\r
+S3150001EE600300000A40204BE2060092E906008CE806\r
+S3150001EE7087FFFFEA000054E3F9FFFF1A40004BE267\r
+S3150001EE80180090E90020A0E3011CA0E3013003E093\r
+S3150001EE90024004E0043093E10600000A0040A0E3CA\r
+S3150001EEA08030A0E3060090E9031091E00420A2E07F\r
+S3150001EEB0060080E9EAFFFFEA098098E1E8FFFF0A18\r
+S3150001EEC00040A0E38030A0E340004BE2F4FFFFEAFC\r
+S3150001EED0000000000000001000009FE50EF0A0E118\r
+S3150001EEE0EC120200000090E5010050E30000A0834F\r
+S3150001EEF00100A0930EF0A0E1000090E5040050E3AC\r
+S3150001EF000000A0130100A0030EF0A0E1000090E5AF\r
+S3150001EF10020050E30000A0130100A0030EF0A0E1DF\r
+S3150001EF200DC0A0E1F0D92DE904B04CE250C04BE28E\r
+S3150001EF3034804BE238D04DE20150A0E10040A0E11F\r
+S3150001EF4048704BE20C00A0E158604BE20810A0E1CA\r
+S3150001EF5030008CE80C0086E81F0200EB0600A0E1F9\r
+S3150001EF600710A0E11C0200EB0800A0E10D0000EB78\r
+S3150001EF700030A0E1000053E30700A0E10100000A10\r
+S3150001EF800100A0E3F0A91BE9060000EB0030A0E1B7\r
+S3150001EF90000053E30800A0E10710A0E1F7FFFF1A04\r
+S3150001EFA05D0200EBF0A91BE9000090E5010050E3CA\r
+S3150001EFB00000A0830100A0930EF0A0E10DC0A0E126\r
+S3150001EFC0F0D92DE904B04CE250C04BE234804BE25B\r
+S3150001EFD038D04DE20150A0E10040A0E148704BE27B\r
+S3150001EFE00C00A0E158604BE20810A0E130008CE86B\r
+S3150001EFF00C0086E8F80100EB0600A0E10710A0E18D\r
+S3150001F000F50100EB0800A0E10D0000EB0030A0E1E6\r
+S3150001F010000053E30700A0E10100000A0100A0E39C\r
+S3150001F020F0A91BE9060000EB0030A0E1000053E364\r
+S3150001F0300800A0E10710A0E1F7FFFF1A360200EB76\r
+S3150001F040F0A91BE9000090E5010050E30000A08350\r
+S3150001F0500100A0930EF0A0E10DC0A0E1F0D92DE9C9\r
+S3150001F06004B04CE250C04BE234804BE238D04DE262\r
+S3150001F0700150A0E10040A0E148704BE20C00A0E184\r
+S3150001F08058604BE20810A0E130008CE80C0086E8DD\r
+S3150001F090D10100EB0600A0E10710A0E1CE0100EBD3\r
+S3150001F0A00800A0E10D0000EB0030A0E1000053E3F1\r
+S3150001F0B00700A0E10100000A0000E0E3F0A91BE956\r
+S3150001F0C0060000EB0030A0E1000053E30800A0E1D8\r
+S3150001F0D00710A0E1F7FFFF1A0F0200EBF0A91BE9E9\r
+S3150001F0E0000090E5010050E30000A0830100A09319\r
+S3150001F0F00EF0A0E10DC0A0E1F0D92DE904B04CE27B\r
+S3150001F10050C04BE234804BE238D04DE20150A0E1D1\r
+S3150001F1100040A0E148704BE20C00A0E158604BE2D0\r
+S3150001F1200810A0E130008CE80C0086E8AA0100EB8B\r
+S3150001F1300600A0E10710A0E1A70100EB0800A0E18D\r
+S3150001F1400D0000EB0030A0E1000053E30700A0E151\r
+S3150001F1500100000A0000E0E3F0A91BE9060000EB4C\r
+S3150001F1600030A0E1000053E30800A0E10710A0E190\r
+S3150001F170F7FFFF1AE80100EBF0A91BE9000090E593\r
+S3150001F180010050E30000A0830100A0930EF0A0E16E\r
+S3150001F1900DC0A0E1F0D92DE904B04CE250C04BE21C\r
+S3150001F1A034804BE238D04DE20150A0E10040A0E1AD\r
+S3150001F1B048704BE20C00A0E158604BE20810A0E158\r
+S3150001F1C030008CE80C0086E8830100EB0600A0E124\r
+S3150001F1D00710A0E1800100EB0800A0E10D0000EBA3\r
+S3150001F1E00030A0E1000053E30700A0E10100000A9E\r
+S3150001F1F00100A0E3F0A91BE9060000EB0030A0E145\r
+S3150001F200000053E30800A0E10710A0E1F7FFFF1A91\r
+S3150001F210C10100EBF0A91BE9000090E5010050E3F4\r
+S3150001F2200000A0830100A0930EF0A0E10DC0A0E1B3\r
+S3150001F23010D82DE90330A0E304B04CE2000050E3FE\r
+S3150001F24014D04DE2A02FA0E120200BE524300BE5E0\r
+S3150001F2500130430224300B051B00000A3C30A0E3B9\r
+S3150001F260000052E31C300BE50030A001C34FA001A2\r
+S3150001F2700300000A020150E300306012C34FA011DF\r
+S3150001F2801400000A10204BE2180002E914301BE5B5\r
+S3150001F2901F0273E30C00008A10204BE2180012E9EA\r
+S3150001F2A08420A0E1A34F82E18330A0E110204BE24C\r
+S3150001F2B0180002E914201BE51C301BE51F0272E34E\r
+S3150001F2C0013043E21C300BE5F2FFFF9A24004BE2CA\r
+S3150001F2D09C0000EB10A81BE904008FE2030090E8F4\r
+S3150001F2E010A81BE90000E0C1000000000DC0A0E16C\r
+S3150001F2F030D82DE904B04CE20140A0E10030A0E194\r
+S3150001F30030204BE228504BE21CD04DE20200A0E136\r
+S3150001F3100510A0E1180082E82F0100EB0500A0E12D\r
+S3150001F320280000EB000050E30040A0E10000A0131C\r
+S3150001F33030A81B190500A0E1180000EB000050E3FE\r
+S3150001F3400400A01130A81B190500A0E1180000EB6C\r
+S3150001F350000050E30400001A20301BE5000053E3CF\r
+S3150001F36030A81BB91E0053E3040000DA24301BE564\r
+S3150001F370000053E30201E0030201A01330A81BE9D8\r
+S3150001F3803C2063E220304BE2030093E9590000EB95\r
+S3150001F39024301BE5000053E30000601230A81BE98E\r
+S3150001F3A0000090E5010050E30000A0830100A09356\r
+S3150001F3B00EF0A0E1000090E5040050E30000A01368\r
+S3150001F3C00100A0030EF0A0E1000090E5020050E369\r
+S3150001F3D00000A0130100A0030EF0A0E10DC0A0E102\r
+S3150001F3E010D82DE904B04CE22CC04BE224404BE28C\r
+S3150001F3F00130A0E10020A0E11CD04DE20C00A0E10B\r
+S3150001F4000410A0E10C008CE8F30000EB0400A0E17D\r
+S3150001F410020000EB0400A0E14A0000EB10A81BE982\r
+S3150001F420043090E5000053E30030A0130130A0033F\r
+S3150001F430043080E50EF0A0E1000051E32900000A46\r
+S3150001F440010051E3010050110000A0030EF0A031AC\r
+S3150001F4500130A0E3010251E3000051310112A03154\r
+S3150001F4600332A031FAFFFF3A020151E300005131A4\r
+S3150001F4708110A0318330A031FAFFFF3A0020A0E3CA\r
+S3150001F480010050E101004020A10050E1A10040200F\r
+S3150001F490E3208221210150E12101402063218221C3\r
+S3150001F4A0A10150E1A1014020E321822103C0A0E195\r
+S3150001F4B0000050E32332B0112112A011EEFFFF1A12\r
+S3150001F4C00E2212E207001C130500000AEC0112E1EC\r
+S3150001F4D0A10180106C0112E121018010EC0012E102\r
+S3150001F4E0A10080100EF0A0E104E02DE544F8FFEB49\r
+S3150001F4F00000A0E30080BDE8000052E370402DE962\r
+S3150001F50020C062E20140A0E10030A0E10060A0E37A\r
+S3150001F5100050A0E30800000A00005CE33032A0E1DD\r
+S3150001F52000E06CE20060A0D3315EA0D13162A0C1DF\r
+S3150001F530115C83C10640A0E10530A0E10410A0E101\r
+S3150001F5400300A0E17080BDE80DC0A0E1F0DD2DE96A\r
+S3150001F5500C3080E204B04CE208D04DE20040A0E15C\r
+S3150001F560600093E8048090E58C0000EB000050E316\r
+S3150001F5700070A0E31C00000A863F8FE2180093E8A2\r
+S3150001F5807F7E87E2035085E1046086E10F7087E2A2\r
+S3150001F59028301BE5233AA0E1063683E16336A0E174\r
+S3150001F5A028300BE5B6225BE17F3EA0E30F3083E214\r
+S3150001F5B00322C2E1033007E0032282E1B6224BE1D6\r
+S3150001F5C025305BE5011008E28030C3E3813383E136\r
+S3150001F5D025304BE528201BE528500BE52C200BE5B3\r
+S3150001F5E030304BE2030093E9F0AD1BE90400A0E1E2\r
+S3150001F5F06F0000EB000050E30400000A7F7EA0E3E9\r
+S3150001F6000F7087E20060A0E30050A0E3DFFFFFEA8E\r
+S3150001F6100400A0E16B0000EB000050E3F8FFFF1AC5\r
+S3150001F620063095E1D9FFFF0A080094E5FF3FE0E3C4\r
+S3150001F630013043E2030050E1350000AABFA360E2B6\r
+S3150001F640FFA78AE2FFAB8AE238005AE31C0000DA20\r
+S3150001F6500060A0E30050A0E3FF3005E20040A0E314\r
+S3150001F660800053E30B00000A0040A0E37F30A0E3D3\r
+S3150001F670035095E00460A6E0010256E32524A0E1CB\r
+S3150001F6800170A023063C82E12644A0E10460A0E1CA\r
+S3150001F6900350A0E1BDFFFFEA000054E3F1FFFF1AAA\r
+S3150001F6A00020A0E3011CA0E3013005E0024006E0D2\r
+S3150001F6B0043093E1EFFFFF0A0040A0E38030A0E3AE\r
+S3150001F6C0EAFFFFEA0A20A0E10010A0E30100A0E39F\r
+S3150001F6D0FF0000EB0040E0E30030E0E3003093E0A0\r
+S3150001F6E00140A4E0042006E0031005E0021091E1C8\r
+S3150001F6F00610A0E10500A0E10A20A0E10040A00358\r
+S3150001F7000140A0137BFFFFEB045080E1C46F81E150\r
+S3150001F710D0FFFFEA010B50E3B7FFFFAAFF3005E276\r
+S3150001F7200040A0E3FF7F80E2800053E3037087E29D\r
+S3150001F7300D00000A0040A0E37F30A0E3035095E0EE\r
+S3150001F7400460A6E01E0276E30500009AA520A0E16A\r
+S3150001F750863F82E1A640A0E1017087E20460A0E154\r
+S3150001F7600350A0E12524A0E1C5FFFFEA000054E310\r
+S3150001F770EFFFFF1A0020A0E3011CA0E3013005E022\r
+S3150001F780024006E0043093E1EDFFFF0A0040A0E3EA\r
+S3150001F7908030A0E3E8FFFFEA000000000000080057\r
+S3150001F7A0000090E5010050E30000A0830100A09352\r
+S3150001F7B00EF0A0E1000090E5040050E30000A01364\r
+S3150001F7C00100A0030EF0A0E1000090E5020050E365\r
+S3150001F7D00000A0130100A0030EF0A0E1F0402DE906\r
+S3150001F7E000C090E508D04DE204C08DE5B620DDE10C\r
+S3150001F7F00730DDE57F4EA0E3040090E50F4084E28B\r
+S3150001F800A333A0E1FF64CCE3227214E0043081E566\r
+S3150001F81001E0A0E10050A0E100008DE50F66C6E31E\r
+S3150001F8201E00001A060090E10230A0031900000A2A\r
+S3150001F8300614A0E10534A0E1254C81E10460A0E1B4\r
+S3150001F8400350A0E1FF2FE0E3012042E20330A0E3F1\r
+S3150001F8501F0276E308208EE500308EE50900008A56\r
+S3150001F8608610A0E108209EE5A54F81E18530A0E143\r
+S3150001F8700460A0E10350A0E1012042E21F0276E309\r
+S3150001F88008208EE5F5FFFF9A0C308EE2600083E8D2\r
+S3150001F89008D08DE2F080BDE800308EE5FBFFFFEA7F\r
+S3150001F8A0040057E10D00000A0624A0E1204C82E184\r
+S3150001F8B00034A0E150108FE2060091E8FF0F47E205\r
+S3150001F8C0030040E2015083E1026084E10C308EE2E4\r
+S3150001F8D008008EE5600083E80330A0E3EDFFFFEA50\r
+S3150001F8E0060090E10430A003EAFFFF0A20108FE230\r
+S3150001F8F0060091E8013005E0024006E0043093E19C\r
+S3150001F9000130A01300308EE5DEFFFFEA00000000A3\r
+S3150001F9100000001000000000000008000DC0A0E17A\r
+S3150001F92070D82DE904B04CE20140A0E10050A0E1FD\r
+S3150001F930580000EB000050E30100000A0100A0E3BB\r
+S3150001F94070A81BE90400A0E1520000EB000050E39F\r
+S3150001F950F9FFFF1A0500A0E1530000EB000050E398\r
+S3150001F9600600000A0400A0E14F0000EB000050E38E\r
+S3150001F97004209415043095150200631070A81B1914\r
+S3150001F9800500A0E1480000EB000050E30400000A76\r
+S3150001F990043095E5000053E30100A0030000E013E5\r
+S3150001F9A070A81BE90400A0E13F0000EB000050E352\r
+S3150001F9B00060A0E10400000A043094E5000053E36E\r
+S3150001F9C00000E0030100A01370A81BE90500A0E1F7\r
+S3150001F9D03A0000EB000050E30300000A0400A0E136\r
+S3150001F9E0360000EB000050E32800001A0500A0E1F4\r
+S3150001F9F0320000EB000050E3EEFFFF1A0400A0E125\r
+S3150001FA002E0000EB000050E3E0FFFF1A041095E51D\r
+S3150001FA10043094E5030051E10100000A000051E3BE\r
+S3150001FA20DCFFFFEA082095E5083094E5030052E182\r
+S3150001FA30F9FFFFCA130000BA0CC085E20C0084E28C\r
+S3150001FA4004209CE5043090E5030052E1F2FFFF8AB1\r
+S3150001FA500300001A0C2095E50C3094E5030052E1F1\r
+S3150001FA60EDFFFF8A042090E504309CE5030052E196\r
+S3150001FA700400008A0500001A0C2094E50C3095E577\r
+S3150001FA80030052E10100009A000051E3CBFFFFEAB7\r
+S3150001FA900000A0E370A81BE9000090E5010050E317\r
+S3150001FAA00000A0830100A0930EF0A0E1000090E504\r
+S3150001FAB0040050E30000A0130100A0030EF0A0E132\r
+S3150001FAC0000090E5020050E30000A0130100A0032E\r
+S3150001FAD00EF0A0E1000052E370402DE920C062E281\r
+S3150001FAE00140A0E10030A0E10060A0E30050A0E3E6\r
+S3150001FAF00800000A00005CE31132A0E100E06CE2BC\r
+S3150001FB000050A0D3106EA0D11052A0C1306C83C199\r
+S3150001FB100640A0E10530A0E10410A0E10300A0E148\r
+S3150001FB207080BDE80C3090E504E02DE50FE0C3E3FD\r
+S3150001FB3050C04EE20020A0E3113482E3113883E382\r
+S3150001FB4002318CE7012082E20A0052E3F9FFFFDA73\r
+S3150001FB501C209FE51330A0E300108CE534E08CE512\r
+S3150001FB603C208CE540308CE538208CE50CC080E5E6\r
+S3150001FB7004F09DE4D84401000DC0A0E100D82DE9B0\r
+S3150001FB8004B04CE278209FE5003092E5013083E233\r
+S3150001FB90003082E56C309FE5002093E5000052E3DA\r
+S3150001FBA09C0080050C00000A0310A0E1020050E150\r
+S3150001FBB00900000A9C2092E5003091E5030052E11C\r
+S3150001FBC0F9FFFF1A020050E138309F150010931516\r
+S3150001FBD09C2091159C2080159C00811524309FE561\r
+S3150001FBE0000083E518209FE5003092E5010053E20D\r
+S3150001FBF0000082150000000A00A81BE94FD9FFEB9F\r
+S3150001FC00FCFFFFEAF4200200E8200200001090E564\r
+S3150001FC1004E02DE5000051E304F09D0400E0A0E3BB\r
+S3150001FC2004F09D0400C091E501005CE104309115EA\r
+S3150001FC300E10A00104308C150420911504108115B5\r
+S3150001FC4000C08215001081150C10A01100E080057E\r
+S3150001FC5000C08015000051E304F09D04F0FFFFEAA7\r
+S3150001FC600030A0E3043080E5083080E50C3080E503\r
+S3150001FC70003080E50EF0A0E10DC0A0E1F0DD2DE938\r
+S3150001FC8004B04CE20040A0E1C8309FE5002093E5B6\r
+S3150001FC90012082E2002083E5083090E508A080E299\r
+S3150001FCA0000053E30030A0130130A003000053E32A\r
+S3150001FCB00A50A0E10900001A0370A0E10560A0E363\r
+S3150001FCC00500A0E1E4D8FFEB7C6080E5787080E573\r
+S3150001FCD034D3FFEB083094E5000053E3F7FFFF1A36\r
+S3150001FCE00C3094E50C8084E2000053E30030A0134D\r
+S3150001FCF00130A003000053E30850A0E10900001AF7\r
+S3150001FD000370A0E10560A0E30500A0E1D2D8FFEBF6\r
+S3150001FD107C6080E5787080E522D3FFEB0C3094E5BA\r
+S3150001FD20000053E3F7FFFF1A28209FE5003092E514\r
+S3150001FD30010053E2000082150400000A0800A0E158\r
+S3150001FD40B1FFFFEB0A00A0E1F06D1BE9AEFFFFEA90\r
+S3150001FD50FAD8FFEBF8FFFFEAF42002000DC0A0E19C\r
+S3150001FD60F0D92DE944219FE504B04CE20050A0E111\r
+S3150001FD7001C0A0E1007092E534619FE5003096E58F\r
+S3150001FD80013083E2003086E5040090E5000050E38F\r
+S3150001FD902C0000DA002095E5010040E2023185E001\r
+S3150001FDA0101093E5012082E2090052E30030A0C35E\r
+S3150001FDB0040085E500108CE5002085E5003085C549\r
+S3150001FDC00C3095E50C0085E2000053E30040A013DA\r
+S3150001FDD00140A003000054E30800000AD0209FE57B\r
+S3150001FDE0003092E5010053E2000082150100000A8D\r
+S3150001FDF00100A0E3F0A91BE9D0D8FFEBFBFFFFEA66\r
+S3150001FE0095D8FFEB0C0095E8032082E0043095E5D8\r
+S3150001FE10441090E5013083E2043085E5090052E3A0\r
+S3150001FE20003091E50A2042C200C0A0E1022185E02E\r
+S3150001FE300710A0E3103082E57C108CE578408CE554\r
+S3150001FE40D8D2FFEBE4FFFFEA441087E5003092E5E4\r
+S3150001FE500140A0E3784083E5002092E50080A0E31D\r
+S3150001FE607C8082E5B1D2FFEB0710A0E1080085E2B4\r
+S3150001FE706AD8FFEB000096E5010040E2AFD8FFEB40\r
+S3150001FE807C1097E5040051E3040000BA050051E334\r
+S3150001FE900840A0D1010000DA060051E30100000A82\r
+S3150001FEA00400A0E1F0A91BE905D4FFEBFBFFFFEA83\r
+S3150001FEB00C8A0200F42002000DC0A0E1F0DF2DE95A\r
+S3150001FEC038A19FE504B04CE204D04DE20190A0E1D7\r
+S3150001FED00360A0E10250A0E10040A0E100809AE5A4\r
+S3150001FEE01C719FE5003097E5013083E2003087E51C\r
+S3150001FEF004C090E500005CE3150000DA002090E5FF\r
+S3150001FF0001C04CE2023180E0012082E2101093E54B\r
+S3150001FF10090052E30030A0C304C080E5001089E562\r
+S3150001FF20002080E5003080C5D8309FE50FE0A0E1D4\r
+S3150001FF3003F0A0E1003097E5010053E200008715C8\r
+S3150001FF400100000A0100A0E3F0AF1BE97BD8FFEB3B\r
+S3150001FF50FBFFFFEA00209AE50330A0E3783082E553\r
+S3150001FF6000109AE500C0A0E37CC081E500009AE597\r
+S3150001FF700C30A0E14C0080E20620A0E10510A0E1D2\r
+S3150001FF8000C08DE53CF0FFEB7C3098E5000053E3C3\r
+S3150001FF901400000A000097E50140A0E3010040E2D9\r
+S3150001FFA066D8FFEB00009AE54C0080E298F0FFEB83\r
+S3150001FFB07C3098E5033043E2030053E303F19F9756\r
+S3150001FFC0040000EAD4FF0100D4FF0100D4FF0100C0\r
+S3150001FFD0E0FF01000040A0E30400A0E1F0AF1BE94F\r
+S3150001FFE0B7D3FFEBFBFFFFEA449088E54FD2FFEB67\r
+S3150001FFF0080084E20810A0E108D8FFEBE4FFFFEA5D\r
+S315000200000C8A0200F4200200980402000DC0A0E14E\r
+S3150002001010D82DE904B04CE201E0A0E180309FE562\r
+S31500020020002093E5012082E2002083E5043090E57A\r
+S31500020030000053E30040A0D30140A0C3000054E3F4\r
+S31500020040012043E20C00000A003090E5042080E51E\r
+S31500020050032180E0101092E5013083E2090053E3A8\r
+S3150002006000108EE5003080E50030A0C3003080C568\r
+S3150002007030309FE50FE0A0E103F0A0E120209FE5EC\r
+S31500020080003092E5013053E20300A0E10030821510\r
+S315000200900100000A0400A0E110A81BE927D8FFEB23\r
+S315000200A0FBFFFFEAF4200200980402000DC0A0E163\r
+S315000200B0F0D92DE904B04CE218C19FE504D04DE217\r
+S315000200C024100BE50050A0E100709CE508619FE555\r
+S315000200D0003096E5013083E2003086E5041090E5B3\r
+S315000200E00A0051E32000000A083090E5080080E289\r
+S315000200F0000053E30040A0130140A003000054E3B4\r
+S315000201001000000A003095E5012081E2013083E00B\r
+S31500020110090053E30A3043C2042085E5032185E042\r
+S3150002012024301BE5103082E5003096E5010053E2EB\r
+S31500020130000086150100000A0100A0E3F0A91BE9F0\r
+S31500020140FED7FFEBFBFFFFEAC3D7FFEB24301BE52D\r
+S3150002015044C090E50720A0E300308CE57C2080E5D2\r
+S31500020160784080E50FD2FFEBEEFFFFEA24304BE248\r
+S31500020170443087E500209CE50140A0E3784082E513\r
+S3150002018000309CE50080A0E37C8083E5E7D1FFEBAD\r
+S315000201900710A0E10C0085E2A0D7FFEB000096E570\r
+S315000201A0010040E2E5D7FFEB7C1097E5040051E33E\r
+S315000201B0040000BA050051E30840A0D1010000DAAC\r
+S315000201C0060051E30100000A0400A0E1F0A91BE9C0\r
+S315000201D03BD3FFEBFBFFFFEA0C8A0200F42002008E\r
+S315000201E00DC0A0E1F0DD2DE968A19FE504B04CE267\r
+S315000201F008D04DE228100BE50040A0E10360A0E123\r
+S315000202000250A0E100809AE54C719FE5003097E527\r
+S31500020210013083E2003087E5041090E50A0051E3DD\r
+S315000202202000000A083090E5080080E2000053E34F\r
+S315000202300050A0130150A003000055E31000000A6D\r
+S31500020240003094E5012081E2013083E0090053E3A6\r
+S315000202500A3043C2042084E5032184E028301BE5EA\r
+S31500020260103082E5003097E5010053E20000871561\r
+S315000202700100000A0100A0E3F0AD1BE9AFD7FFEBD6\r
+S31500020280FBFFFFEA74D7FFEB28301BE544C090E57D\r
+S315000202900720A0E300308CE57C2080E5785080E5DD\r
+S315000202A0C0D1FFEBEEFFFFEA00209AE50330A0E3A0\r
+S315000202B0783082E500109AE500C0A0E37CC081E5B3\r
+S315000202C000009AE50C30A0E14C0080E20620A0E195\r
+S315000202D00510A0E100C08DE567EFFFEB7C3098E5E5\r
+S315000202E0000053E31400000A000097E50140A0E372\r
+S315000202F0010040E291D7FFEB00009AE54C0080E254\r
+S31500020300C3EFFFEB7C3098E5033043E2030053E38F\r
+S3150002031003F19F97040000EA280302002803020063\r
+S3150002032028030200340302000040A0E30400A0E117\r
+S31500020330F0AD1BE9E2D2FFEBFBFFFFEA28304BE20E\r
+S31500020340443088E579D1FFEB0C0084E20810A0E185\r
+S3150002035032D7FFEBE3FFFFEA0C8A0200F420020029\r
+S315000203600DC0A0E170D82DE904B04CE20160A0E115\r
+S31500020370B4409FE5003094E5013083E2003084E525\r
+S31500020380041090E50A0051E31F00000A083090E5C8\r
+S31500020390082080E2000053E30050A0130150A0039E\r
+S315000203A0000055E30F00000A003090E5012081E2CB\r
+S315000203B0013083E0090053E30A3043C2033180E08F\r
+S315000203C0042080E5106083E5003094E5010053E2E5\r
+S315000203D0000084150100000A0100A0E370A81BE9D1\r
+S315000203E056D7FFEBFBFFFFEA0200A0E11AD7FFEBAD\r
+S315000203F0443090E50720A0E3006083E57C2080E599\r
+S31500020400785080E567D1FFEBEEFFFFEA003094E516\r
+S31500020410010053E2000084150100000A0000A0E377\r
+S3150002042070A81BE945D7FFEBFBFFFFEAF4200200A9\r
+S315000204300DC0A0E110D82DE904B04CE250C09FE5F2\r
+S3150002044000309CE5013083E200308CE5043090E513\r
+S31500020450000053E30040A0D30140A0C3000054E3D0\r
+S31500020460003090150331801010209315002081155D\r
+S3150002047000309CE5013053E20300A0E100308C1508\r
+S315000204800100000A0400A0E110A81BE92BD7FFEB2C\r
+S31500020490FBFFFFEAF42002000DC0A0E130D82DE9EF\r
+S315000204A00C3090E50040A0E1000053E30050A01399\r
+S315000204B00150A003000055E304B04CE20C0080E2B8\r
+S315000204C030A81B19E4D6FFEB0C0094E8032082E067\r
+S315000204D0043094E5441090E5013083E2043084E56B\r
+S315000204E0090052E3003091E50A2042C200C0A0E1B1\r
+S315000204F0022184E00710A0E3103082E57C108CE52F\r
+S3150002050078508CE530681BE926D1FFEA0DC0A0E1E0\r
+S3150002051030D82DE904B04CE234409FE500C094E5A2\r
+S3150002052001C08CE200C084E5BEF1FFEB0050A0E101\r
+S31500020530003094E5013053E20300A0E10030841557\r
+S315000205400100000A0500A0E130A81BE9FBD6FFEB7B\r
+S31500020550FBFFFFEAF42002000DC0A0E1F0DF2DE967\r
+S3150002056004B04CE208D04DE20070A0E1F4309FE501\r
+S3150002057000C093E501C08CE200C083E520F1FFEBE9\r
+S3150002058030000BE5103497E5000053E30030A0136A\r
+S315000205900130A003000053E31D00001A28A04BE21D\r
+S315000205A004302AE5418E87E20790A0E30800A0E125\r
+S315000205B0A9D6FFEB446090E50040A0E1001096E565\r
+S315000205C00700A0E1F2EFFFEB0050A0E1000055E3C7\r
+S315000205D00400A0E10410A0E11F00000A0030A0E31D\r
+S315000205E0783084E57C9084E5EED0FFEB045086E516\r
+S315000205F0103497E5000053E3EBFFFF1A2C301BE59E\r
+S315000206000A40A0E1000053E30A00001A0A00A0E132\r
+S315000206107DFDFFEB4C209FE5003092E5010053E2A1\r
+S31500020620000082150100000A30001BE5F0AF1BE94D\r
+S31500020630C2D6FFEBFBFFFFEA0400A0E186D6FFEB82\r
+S315000206400010A0E10800A0E174D6FFEB2C301BE5F8\r
+S31500020650000053E3F7FFFF1AEBFFFFEA0A00A0E1EF\r
+S315000206606ED6FFEBE1FFFFEAF42002000DC0A0E127\r
+S3150002067000D82DE904B04CE21C209FE5003092E53B\r
+S31500020680013053E20300A0E1003082150000000AA7\r
+S3150002069000A81BE9A9D6FFEBFCFFFFEAF420020043\r
+S315000206A00DC0A0E110D82DE904B04CE20040A0E153\r
+S315000206B09AEFFFEB0030A0E3103484E510A81BE9A3\r
+S315000206C00DC0A0E1F0D92DE904B04CE20040A0E152\r
+S315000206D080309FE5002093E5012082E2002083E539\r
+S315000206E0103490E5418E80E2000053E30030A013FF\r
+S315000206F00130A003000053E30850A0E10900001AEC\r
+S315000207000370A0E10560A0E30500A0E152D6FFEB6D\r
+S315000207107C6080E5787080E5A2D0FFEB103494E52A\r
+S31500020720000053E3F7FFFF1A28209FE5003092E509\r
+S31500020730010053E2000082150400000A0800A0E14D\r
+S3150002074014309FE50FE0A0E103F0A0E1F0A91BE958\r
+S315000207507AD6FFEBF8FFFFEAF42002000CFC010058\r
+S31500020760013040E20DC0A0E1100053E330D82DE97C\r
+S3150002077004B04CE20040A0E10500009ADEE9FFEB7E\r
+S315000207800020E0E31630A0E3003080E50200A0E19D\r
+S3150002079030A81BE94DF2FFEB000050E30300001AFC\r
+S315000207A0D5E9FFEB0020E0E30430A0E3F5FFFFEA22\r
+S315000207B048209FE5045192E7010055E30B00000A29\r
+S315000207C0020055E30700000A0130A0E3043182E784\r
+S315000207D043F2FFEB0400A0E10FE0A0E105F0A0E187\r
+S315000207E00020A0E3E8FFFFEA3DF2FFEBFBFFFFEA92\r
+S315000207F03BF2FFEB0400A0E12FF2FFEBF7FFFFEA6B\r
+S315000208001CB0020004E02DE50030A0E1040090E5F2\r
+S31500020810000050E304F09D04003093E5000053E32A\r
+S3110002082004F09D0404E09DE46BDDFFEA99\r
+S3150002082C0000000001000000000000000E0C000099\r
+S3150002083C000600000100000000060000020C000089\r
+S3150002084C010600001E000000010600000E0C00004E\r
+S3150002085C1F060000010000001F060000020C00002B\r
+S3150002086C000800000100000000080000020C000055\r
+S3150002087CFF0F000001000000FF0F00000200000045\r
+S3150002088C39332E3720666D202020000039342E375E\r
+S3150002089C20666D202020000039362E3720666D200A\r
+S315000208AC2020000039372E3120666D2020200000D2\r
+S315000208BC25642E256420666D202020200000000071\r
+S315000208CC5363616E6E696E672E2E2E00256420733D\r
+S315000208DC746174696F6E7320202000005265636F19\r
+S315000208EC7264696E672053746F7020005265636F71\r
+S315000208FC7264696E67205374617274004C50522B89\r
+S3150002090C4C4D52204D6F6465202020005374657245\r
+S3150002091C656F204D6F64652020202000566F6C3A5F\r
+S3150002092C20253033640000004D61726B6572204FD6\r
+S3150002093C666600004D61726B6572204F6E20000078\r
+S3150002094C445249204F666620202020202020200079\r
+S3150002095C445249204F6E20202020202020202000A7\r
+S3150002096C426C61636B20426F78204F6666202020B2\r
+S3150002097C20000000426C61636B20426F78204F6E40\r
+S3150002098C2020202020000000564F4C2B20253033EF\r
+S3150002099C64000000564F4C2D2025303364000000B5\r
+S315000209AC5265633A202530386400000053544D508A\r
+S315000209BC3336303020506C61796572005354464D93\r
+S315000209CC20313030302044656D6F00005369676EFC\r
+S315000209DC616C3D25303564005041535300000000D4\r
+S315000209EC4641494C000000000A746573745F6578D1\r
+S315000209FC69742025732072657475726E20636F6438\r
+S31500020A0C6520646563203D20256420686578203D59\r
+S31500020A1C2025780A0A0000004572726F723A20206D\r
+S31500020A2C25732052656769737465722077726974CF\r
+S31500020A3C65206661696C6564206174206164647208\r
+S31500020A4C65737320307825782E200A095265616405\r
+S31500020A5C2076616C3A20307825782C2045787065A2\r
+S31500020A6C637465642076616C3A2030782578204D63\r
+S31500020A7C61736B2030782578204572726F724269E9\r
+S31500020A8C74733A20307825780A0000004572726F2A\r
+S31500020A9C723A202025732052656769737465722039\r
+S31500020AAC52656164206661696C65642061742061BB\r
+S31500020ABC64647265737320307825782E200A095285\r
+S31500020ACC6561642076616C3A20307825782C204555\r
+S31500020ADC787065637465642076616C3A203078258B\r
+S31500020AEC78204D61736B2030782578204572726FB1\r
+S31500020AFC724269747320307825780A004E65772025\r
+S31500020B0C7472616E64282920736565643A203078A4\r
+S31500020B1C25780A001800000000000000C05D0000E5\r
+S31500020B2C0000000000366E010000000000A8D4553B\r
+S31500020B3C000000000060D71D140000004272617AAA\r
+S31500020B4C6F2076657273696F6E20696E666F726D51\r
+S31500020B5C6174696F6E20697320756E617661696C5A\r
+S31500020B6C61626C6520696E2074686973207379738F\r
+S31500020B7C74656D20636F6E66696775726174696FF1\r
+S31500020B8C6E2E0A004272617A6F2062697466696C13\r
+S31500020B9C6520696E636C7564657320696E666F7227\r
+S31500020BAC6D6174696F6E20697320756E6176616909\r
+S31500020BBC6C61626C6520696E207468697320737946\r
+S31500020BCC7374656D20636F6E66696775726174699D\r
+S31500020BDC6F6E2E0A000000004272617A6F20626903\r
+S31500020BEC7466696C6520696E666F726D6174696F85\r
+S31500020BFC6E20697320756E617661696C61626C65D3\r
+S31500020C0C20696E20746869732073797374656D201C\r
+S31500020C1C636F6E66696775726174696F6E2E0A0010\r
+S31500020C2C00000000010001000000000000000000AE\r
+S31500020C3C00000100E0010000140001011400140080\r
+S31500020C4C0000000004000100706C6C5F6672657136\r
+S31500020C5C203D2025640A0000706C6C206469736167\r
+S31500020C6C626C65640A000000637075636C6B5F648A\r
+S31500020C7C6976203D2025640A0000000068627573BF\r
+S31500020C8C636C6B5F646976203D2025640A00000064\r
+S31500020C9C78627573636C6B5F646976203D2025649C\r
+S31500020CAC0A000000656D69636C6B5F646976203DB2\r
+S31500020CBC2025640A00000000656D69636C6B206474\r
+S31500020CCC697361626C65640A0000000067706D6985\r
+S31500020CDC636C6B5F646976203D2025640A00000014\r
+S31500020CEC67706D69636C6B2064697361626C6564B1\r
+S31500020CFC0A000000737370636C6B5F646976203D47\r
+S31500020D0C2025640A00000000737370636C6B206408\r
+S31500020D1C697361626C65640A000000007370646931\r
+S31500020D2C66636C6B5F646976203D2025640A00005D\r
+S31500020D3C7370646966636C6B2064697361626C655B\r
+S31500020D4C640A000069726F765F646976203D20251D\r
+S31500020D5C640A000069725F646976203D2025640A84\r
+S31500020D6C000000007573625F656E61626C65203D02\r
+S31500020D7C2025640A0000000068627573636C6B5F61\r
+S31500020D8C6175746F736C6F775F72617465203D2049\r
+S31500020D9C25640A00637075636C6B5F696E746572A9\r
+S31500020DAC727570745F77616974203D2025640A0040\r
+S31500020DBC5573657220617373657274696F6E206602\r
+S31500020DCC61696C65643A20222573222C2061742099\r
+S31500020DDC25733A25640A0000655468726561644499\r
+S31500020DEC6174612D3E7468726561645F68616E64DC\r
+S31500020DFC6C6520213D202D31000000002F686F6D9F\r
+S31500020E0C652F616D617274696E2F72657662312F10\r
+S31500020E1C73746D70333630302F76616C69642F744F\r
+S31500020E2C657374732F73616E64626F782F616D6173\r
+S31500020E3C7274696E2F756E69742F6272617A6F2F76\r
+S31500020E4C73645F706C617965722F65746872656123\r
+S31500020E5C642E630065546872656164446174612D25\r
+S31500020E6C3E7468726561645F68616E646C652021AC\r
+S31500020E7C3D2030006554687265616444617461207A\r
+S31500020E8C213D204E554C4C006D7574657820213DE4\r
+S31500020E9C204E554C4C00000073656D6120213D209F\r
+S31500020EAC4E554C4C00000000666C616720213D20BB\r
+S31500020EBC4E554C4C00000000654D61696C426F78D2\r
+S31500020ECC20213D204E554C4C00000000654D6169B9\r
+S31500020EDC6C426F78000000000A4552524F523A207B\r
+S31500020EEC54696D656F75742077616974696E6720D4\r
+S31500020EFC666F7220444D41204368616E6E656C28A4\r
+S31500020F0C732920746F2052657365742E0A000000D3\r
+S31500020F1C6461634465636F646572446174612E64D3\r
+S31500020F2C616342756666657220213D204E554C4CB6\r
+S31500020F3C000000002F686F6D652F616D6172746918\r
+S31500020F4C6E2F72657662312F73746D703336303054\r
+S31500020F5C2F76616C69642F74657374732F73616E6B\r
+S31500020F6C64626F782F616D617274696E2F756E692A\r
+S31500020F7C742F6272617A6F2F73645F706C6179651C\r
+S31500020F8C722F656173796461632E630064616344D5\r
+S31500020F9C65636F646572446174612E6465636F6424\r
+S31500020FAC657242756666657220213D204E554C4C23\r
+S31500020FBC000000006C63646D7574657820213D2019\r
+S31500020FCC4E554C4C000000002F686F6D652F616DFD\r
+S31500020FDC617274696E2F72657662312F73746D70DD\r
+S31500020FEC333630302F76616C69642F746573747383\r
+S31500020FFC2F73616E64626F782F616D617274696EA4\r
+S3150002100C2F756E69742F6272617A6F2F73645F70BB\r
+S3150002101C6C617965722F6C63642E6300300000007C\r
+S3150002102C646174615F726561647920213D204E555D\r
+S3150002103C4C4C00002F686F6D652F616D617274697F\r
+S3150002104C6E2F72657662312F73746D703336303053\r
+S3150002105C2F76616C69642F74657374732F73616E6A\r
+S3150002106C64626F782F616D617274696E2F756E6929\r
+S3150002107C742F6272617A6F2F73645F706C6179651B\r
+S3150002108C722F627574746F6E732E6300646D616D6C\r
+S3150002109C7574657820213D204E554C4C000000009D\r
+S315000210AC2F686F6D652F616D617274696E2F726533\r
+S315000210BC7662312F73746D70333630302F76616CE5\r
+S315000210CC69642F74657374732F73616E64626F78BF\r
+S315000210DC2F616D617274696E2F756E69742F6272EF\r
+S315000210EC617A6F2F73645F706C617965722F646DB0\r
+S315000210FC615F6D656D6370792E630000E00100001F\r
+S3150002110C05000C01000000000000000000000100B8\r
+S3150002111C2F6465762F747479646961670000000028\r
+S3150002112C2F6465762F68616C646961670000000044\r
+S3150002113C082008000D0A000025730A0068616C6419\r
+S3150002114C6961675F7365745F636F6E6669670000DA\r
+S3150002115C30313233343536373839414243444546D9\r
+S3150002116C00000000303132333435363738394142DB\r
+S3150002117C43444546000000003031323334353637AD\r
+S3150002118C383900003031323334353637383961620A\r
+S3150002119C63646566000000003C6E756C6C3E000074\r
+S315000211AC3C4E6F74206120737472696E673A2030FC\r
+S315000211BC780000003E0000003C42616420666F72BB\r
+S315000211CC6D617420737472696E673A2000000000B8\r
+S315000211DC203A00003E0A0000253038583A2000001A\r
+S315000211EC2530325820000000207C000025630000C8\r
+S315000211FC7C0A0000253038582000000020202020D0\r
+S3150002120C2020202020000000253034582000000029\r
+S3150002121C49646C6520546872656164007265616428\r
+S3150002122C790000002C205072696F726974793A2029\r
+S3150002123C00000000736C656570696E670000000043\r
+S3150002124C636F756E74656420736C6565700000005F\r
+S3150002125C6372656174696E6700000000756E6B6E71\r
+S3150002126C6F776E207374617465000000657869741B\r
+S3150002127C6564000073757370656E6465642B00009B\r
+S3150002128C72756E6E696E67006D61696E00000000A4\r
+S3150002129C8CAF020073747264657600006275672007\r
+S315000212AC696E2076667072696E74663A2062616443\r
+S315000212BC2062617365000000286E756C6C29000053\r
+S315000212CC0101010101010101808080808080808002\r
+S315000212DC0000F03F00000000C808020000000000F9\r
+S315000212EC00000000000000000000000000000000EA\r
+S315000212FC00000000000102020303030304040404B9\r
+S3150002130C040404040505050505050505050505057D\r
+S3150002131C050505050606060606060606060606065D\r
+S3150002132C0606060606060606060606060606060649\r
+S3150002133C060606060707070707070707070707072D\r
+S3150002134C0707070707070707070707070707070719\r
+S3150002135C0707070707070707070707070707070709\r
+S3150002136C07070707070707070707070707070707F9\r
+S3150002137C07070707080808080808080808080808DD\r
+S3150002138C08080808080808080808080808080808C9\r
+S3150002139C08080808080808080808080808080808B9\r
+S315000213AC08080808080808080808080808080808A9\r
+S315000213BC0808080808080808080808080808080899\r
+S315000213CC0808080808080808080808080808080889\r
+S315000213DC0808080808080808080808080808080879\r
+S315000213EC0808080808080808080808080808080869\r
+S309000213FC08080808C5\r
+S3150002140000000000A8210100A8210100A821010076\r
+S31500021410A8210100A8210100A8210100A82101009C\r
+S31500021420A8210100A8210100A8210100A82101008C\r
+S31500021430A8210100A8210100A8210100A82101007C\r
+S31500021440A8210100A8210100A8210100A82101006C\r
+S31500021450A8210100A8210100A8210100A82101005C\r
+S31500021460A8210100A8210100A8210100A82101004C\r
+S31500021470A8210100A8210100A8210100A82101003C\r
+S31500021480A8210100A8210100A8210100A82101002C\r
+S31500021490A8210100A8210100A8210100A82101001C\r
+S315000214A0A8210100A8210100A8210100A82101000C\r
+S315000214B0A8210100A8210100A8210100A8210100FC\r
+S315000214C0A8210100A8210100A8210100A8210100EC\r
+S315000214D0A8210100A8210100A8210100A8210100DC\r
+S315000214E0A8210100A8210100A8210100A8210100CC\r
+S315000214F0A8210100A8210100A8210100A8210100BC\r
+S31500021500A8210100A821010000000000000000003F\r
+S3150002151000000000000000000000000000000000C3\r
+S3150002152000000000000000000000000000000000B3\r
+S3150002153000000000000000000000000000000000A3\r
+S315000215400000000000000000000000000000000093\r
+S315000215500000000000000000000000000000000083\r
+S315000215600000000000000000000000000000000073\r
+S315000215700000000000000000000000000000000063\r
+S315000215800000000000000000000000000000000053\r
+S315000215900000000000000000000000000000000043\r
+S315000215A00000000000000000000000000000000033\r
+S315000215B00000000000000000000000000000000023\r
+S315000215C00000000000000000000000000000000013\r
+S315000215D00000000000000000000000000000000003\r
+S315000215E000000000000000000000000000000000F3\r
+S315000215F000000000000000000000000000000000E3\r
+S3150002160000000000000000000000000000000000D2\r
+S3150002161000000000000000000000000000000000C2\r
+S3150002162000000000000000000000000000000000B2\r
+S3150002163000000000000000000000000000000000A2\r
+S315000216400000000000000000000000000000000092\r
+S315000216500000000000000000000000000000000082\r
+S315000216600000000000000000000000000000000072\r
+S315000216700000000000000000000000000000000062\r
+S315000216800000000000000000000000000000000052\r
+S315000216900000000000000000000000000000000042\r
+S315000216A00000000000000000000000000000000032\r
+S315000216B00000000000000000000000000000000022\r
+S315000216C00000000000000000000000000000000012\r
+S315000216D00000000000000000000000000000000002\r
+S315000216E000000000000000000000000000000000F2\r
+S315000216F000000000000000000000000000000000E2\r
+S3150002170000000000000000000000000000000000D1\r
+S31500021710A903000001000000000000000000000014\r
+S31500021720010000000000406000000000FFFF000012\r
+S31500021730000000000100000001000000000000009F\r
+S315000217400000000000000000D0000000D0000000F1\r
+S315000217500000000000000000000000000000000081\r
+S315000217600000000000000000010000000000000070\r
+S31500021770000000002F40A6A4C823A08121AFFF00CD\r
+S315000217800000000000065F06000003000300147E4E\r
+S31500021790147E14002E6B3A006636186C667749364C\r
+S315000217A050480000040703001C6341000041631C0B\r
+S315000217B00066187E186600103810000080E060008F\r
+S315000217C0000808080000606000006030180C063E41\r
+S315000217D0615D433E02017F0000426151494642413A\r
+S315000217E0494936001C127F102F454549313E4B4967\r
+S315000217F0493003611109073649494936464949299B\r
+S315000218001E0036360000008076360008142241009B\r
+S315000218101414141400412214080002016D05033C3D\r
+S31500021820425A1A1C7C1211127C7F494949363E41A2\r
+S315000218304141227F4141413E7F494949417F090950\r
+S3150002184009013E414949717F0808087F41417F41AC\r
+S315000218504170417F01007F081422417F4040404091\r
+S315000218607F020C027F7F021C207F3E4141413E7F68\r
+S31500021870090909063E4141617E7F091929462E4919\r
+S3150002188049493201017F01013F4040403F031C604C\r
+S315000218901C030F700C700F6314081463030C700C96\r
+S315000218A0036151494543007F414100060C183060EF\r
+S315000218B00041417F000406030604404040404003C5\r
+S315000218C00704000038442478007F2844380038444E\r
+S315000218D04444003844283F003854544800107C12CF\r
+S315000218E012004C4A4A3C007E1008700000007A0042\r
+S315000218F00020403A00007E1824000000007E00000E\r
+S3150002190078083008787C0804780038444438007E29\r
+S3150002191012221C001C12127E007C080404005C5475\r
+S31500021920740000087E4820003C40407C001C204099\r
+S31500021930201C3C4038403C44281028440C90503C23\r
+S315000219400064544C44000836414100000077000010\r
+S315000219504141360800020102010002016D05030041\r
+S315000219602E008200000000000000000000000000BF\r
+S31500021970000000000000000000008300C900000013\r
+S31500021980000000000000000000000000000000004F\r
+S3150002199000000000CA002201000000000000000052\r
+S315000219A0000000000000000000000000000023010B\r
+S315000219B0840100000000000000000000000000009A\r
+S315000219C000000000000000008501CE0100000000BA\r
+S315000219D000000000000000000000000000000000FF\r
+S315000219E00000CF011E0200000000000000000000FF\r
+S315000219F00000000000000000000000001F026F024D\r
+S31500021A0000000000000000000000000000000000CE\r
+S31500021A100000000000007002BB020000000000008F\r
+S31500021A2000000000000000000000000000000000AE\r
+S31500021A30BC021203000000000000000000000000CB\r
+S31500021A40000000000000000000001303690300000C\r
+S31500021A50000000000000000000000000000000007E\r
+S31500021A60000000006A03A20300000000000000005C\r
+S31500021A70000000000000000000000000000000005E\r
+S31500021A80000000000000000000000000000000004E\r
+S31500021A90000000000000000000000000000000003E\r
+S31500021AA0000000000000000000000000000000002E\r
+S31500021AB00000000000000000000000009DFFFFFF84\r
+S31500021AC00000000000000000E0010000100000001D\r
+S31500021AD002000000C70100000D0000000200000025\r
+S31500021AE0E00100000C00000002000000C20100003C\r
+S31500021AF00A00000002000000C20100000900000006\r
+S31500021B0003000000B8010000080000000300000006\r
+S31500021B10E00100000800000003000000C701000009\r
+S31500021B200700000003000000A401000006000000F8\r
+S31500021B3003000000C20100000600000004000000CD\r
+S31500021B40E00100000600000004000000A9010000F8\r
+S31500021B500500000004000000C201000005000000AC\r
+S31500021B6004000000DB010000050000000400000084\r
+S31500021B70900100000400000005000000A40100001E\r
+S31500021B800400000005000000B80100000400000087\r
+S31500021B9005000000CC010000040000000500000062\r
+S31500021BA0E0010000040000000500000077010000CB\r
+S31500021BB0030000000600000086010000030000008A\r
+S31500021BC00600000095010000030000000600000068\r
+S31500021BD0A40100000300000006000000B30100009B\r
+S31500021BE00300000006000000C2010000030000001E\r
+S31500021BF007000000D10100000300000007000000FA\r
+S31500021C00E001000003000000070000004A01000096\r
+S31500021C10020000000700000054010000020000005C\r
+S31500021C20070000005E01000002000000080000003C\r
+S31500021C3068010000020000000800000072010000B6\r
+S31500021C4002000000080000007C0100000200000003\r
+S31500021C5008000000860100000200000008000000E3\r
+S31500021C609001000002000000090000009A01000035\r
+S31500021C700200000009000000A401000002000000AA\r
+S31500021C800900000000000000000000000000000043\r
+S31500021C90000000000000000000000000000000003C\r
+S31500021CA0000000000000000000000000000000002C\r
+S31500021CB0BA4A0400FB39D11BBC4A04003D69E11B48\r
+S31500021CC0BE4A04007F98F11BC14A0400C2C7011C28\r
+S31500021CD0C34A040004F7111CC54A04004626221C06\r
+S31500021CE0C74A04008955321CC94A0400CB84421CE7\r
+S31500021CF0CB4A04000DB4521CCD4A040050E3621CC8\r
+S31500021D00C04C0400A969B31BD24C0400E32BC31BCD\r
+S31500021D10D44C04001DEED21BD64C040056B0E21B76\r
+S31500021D20D84C04009072F21BDA4C0400CA34021C2E\r
+S31500021D30DC4C040004F7111CDE4C04003EB9211CE5\r
+S31500021D40E14C0400787B311CE34C0400B13D411C9C\r
+S31500021D50E54C0400EBFF501CE74C040025C2601C56\r
+S31500021D60E94E04004FD6B51BEB4E04001831C51BD5\r
+S31500021D70ED4E0400E18BD41BE04E0400AAE6E31B01\r
+S31500021D80F24E04007241F31BF44E04003B9C021C0B\r
+S31500021D90F64E040004F7111CF84E0400CD51211C26\r
+S31500021DA0FA4E040096AC301CFC4E04005E07401C42\r
+S31500021DB0FE4E040027624F1C014F0400F0BC5E1C5D\r
+S31500021DC003510400EE23B81B05510400711CC71B06\r
+S31500021DD007510400F514D61B09510400790DE51BC1\r
+S31500021DE00B510400FD05F41B0D51040080FE021C7C\r
+S31500021DF00051040004F7111C1251040088EF201C44\r
+S31500021E00145104000BE82F1C165104008FE03E1CEF\r
+S31500021E101851040013D94D1C1A51040097D15C1CA9\r
+S31500021E201C530400C954BA1B1E530400D3EFC81B2B\r
+S31500021E3021530400DC8AD71B23530400E625E61B44\r
+S31500021E4025530400F0C0F41B27530400FA5B031C5D\r
+S31500021E502953040004F7111C2B5304000E92201C74\r
+S31500021E602D530400182D2F1C2053040022C83D1C9C\r
+S31500021E70325304002C634C1C3453040035FE5A1CA6\r
+S31500021E8036550400EF6ABC1B38550400F2ACCA1B77\r
+S31500021E903A550400F6EED81B3C550400F930E71B10\r
+S31500021EA03E550400FD72F51B4155040000B5031CA6\r
+S31500021EB04355040004F7111C455504000839201C3B\r
+S31500021EC0475504000B7B2E1C495504000FBD3C1CD4\r
+S31500021ED04B55040012FF4A1C4D5504001641591C6D\r
+S31500021EE0405704003C68BE1B525704005E55CC1B8B\r
+S31500021EF0545704007F42DA1B56570400A02FE81BF2\r
+S31500021F0058570400C11CF61B5A570400E309041C67\r
+S31500021F105C57040004F7111C5E57040025E41F1CDD\r
+S31500021F206157040046D12D1C6357040068BE3B1C52\r
+S31500021F306557040089AB491C67570400AA98571CC9\r
+S31500021F4069590400644EC01B6B5904007FEACD1B1D\r
+S31500021F506D5904009986DB1B60590400B422E91B03\r
+S31500021F6072590400CFBEF61B74590400E95A041CC8\r
+S31500021F707659040004F7111C785904001F931F1C9C\r
+S31500021F807A590400392F2D1C7C59040054CB3A1C73\r
+S31500021F907E5904006F67481C815904008903561C48\r
+S31500021FA0835B0400F01EC21B855B04009E6DCF1B83\r
+S31500021FB0875B04004CBCDC1B895B0400FA0AEA1B43\r
+S31500021FC08B5B0400A859F71B8D5B040056A8041C02\r
+S31500021FD0805B040004F7111CB40D0100280F0100F8\r
+S31500021FE05C26010064260100581001006010010001\r
+S31500021FF034130100100D01005813010030140100C2\r
+S31500022000CC140100CC1501005C26010064260100F7\r
+S315000220103C17010050170100B41701002C180100EB\r
+S315000220204C1801006C1801000000000000000000BE\r
+S315000220301C200200F41F0200DC80020012000000D5\r
+S31500022040010000000000000008000000000000007F\r
+S315000220500000000000000000000000000000000078\r
+S315000220600000000000000000000000000000000068\r
+S315000220700000000000000000000000000000000058\r
+S315000220800000000000000000000000000000000048\r
+S315000220900000000000000000000000000000000038\r
+S315000220A00000000000000000000000000000000028\r
+S315000220B00000000000000000000000000000000018\r
+S315000220C00000000000000000000000000000000008\r
+S315000220D000000000000000000000000000000000F8\r
+S315000220E000000000DC2601000000000001000000E4\r
+S315000220F0300000000100000064210200D88A0200BC\r
+S3150002210000000000000000000000000000000000C7\r
+S3150002211000000000000000000000000000000000B7\r
+S3150002212000000000008F0100000000005C26010094\r
+S31500022130642601000000000000000000000000000C\r
+S315000221402020202020202020202020202020202087\r
+S315000221503030303030303030303030303030303077\r
+S3150002216000000000000000000300050007000B004D\r
+S315000221700D001100130017001D001F002500290085\r
+S315000221802B002F0035003B003D004300470049006D\r
+S315000221904F00530059006100650067006B006D0037\r
+S315000221A071007F00830089008B00950097009D00D7\r
+S315000221B0A300A700AD00B300B500BF00C100C50073\r
+S315000221C0C700EF001D02830600E1F505640000006A\r
+S315000221D01C1102002C11020000200200A4140100AE\r
+S315000221E0B8140100D0800200001000002C11020079\r
+S315000221F000000000D81F02001018010000000000B5\r
+S3150002220030200200001000003C820100DC180100B0\r
+S31500022210E4800100BC82010064D10100F80C0100D7\r
+S3150002222018800100485501007CC401005C5601007B\r
+S31500022230F45A01003C640100D037010054820100C7\r
+S31500022240FC800100D48201007CD1010030800100B3\r
+S315000222506055010094C401000C5B01005464010046\r
+S31560000000000000000000000000000000000000008A\r
+S31560000010000000000000000000000000000000007A\r
+S31560000020000000000000000000000000000000006A\r
+S31560000030000000000000000000000000000000005A\r
+S3156000004000000000CA1062006003006062001E00CB\r
+S31560000050000000000000000000000000000000003A\r
+S31560000060000000000000000000000000000000002A\r
+S31560000070000000000000000000000000000000001A\r
+S31560000080000000000000000000000000000000000A\r
+S3156000009000000000000000000000000000000000FA\r
+S315600000A000000000000000000000000000000000EA\r
+S315600000B000000000000000000000000000000000DA\r
+S315600000C000000000000000000000000000000000CA\r
+S315600000D000000000000000000000000000000000BA\r
+S315600000E000000000000000000000000000000000AA\r
+S315600000F0000000000000000000000000000000009A\r
+S315600001000000000000000000000000000000000089\r
+S315600001100000000000000000000000000000000079\r
+S315600001200000000000000000000000000000000069\r
+S315600001300000000000000000000000000000000059\r
+S315600001400000000000000000000000000000000049\r
+S315600001500000000000000000000000000000000039\r
+S315600001600000000000000000000000000000000029\r
+S315600001700000000000000000000000000000000019\r
+S315600001800000000000000000000000000000000009\r
+S3156000019000000000000000000000000000000000F9\r
+S315600001A000000000000000000000000000000000E9\r
+S315600001B000000000000000000000000000000000D9\r
+S315600001C000000000000000000000000000000000C9\r
+S315600001D000000000000000000000000000000000B9\r
+S315600001E000000000000000000000000000000000A9\r
+S315600001F00000000000000000000000000000000099\r
+S315600002000000000000000000000000000000000088\r
+S315600002100000000000000000000000000000000078\r
+S315600002200000000000000000000000000000000068\r
+S315600002300000000000000000000000000000000058\r
+S315600002400000000000000000000000000000000048\r
+S315600002500000000000000000000000000000000038\r
+S315600002600000000000000000000000000000000028\r
+S315600002700000000000000000000000000000000018\r
+S315600002800000000000000000000000000000000008\r
+S3156000029000000000000000000000000000000000F8\r
+S315600002A000000000000000000000000000000000E8\r
+S315600002B000000000000000000000000000000000D8\r
+S315600002C000000000000000000000000000000000C8\r
+S315600002D000000000000000000000000000000000B8\r
+S315600002E000000000000000000000000000000000A8\r
+S315600002F00000000000000000000000000000000098\r
+S315600003000000000000000000000000000000000087\r
+S315600003100000000000000000000000000000000077\r
+S315600003200000000000000000000000000000000067\r
+S315600003300000000000000000000000000000000057\r
+S315600003400000000000000000000000000000000047\r
+S315600003500000000000000000000000000000000037\r
+S315600003600000000000000000000000000000000027\r
+S315600003700000000000000000000000000000000017\r
+S315600003800000000000000000000000000000000007\r
+S3156000039000000000000000000000000000000000F7\r
+S315600003A000000000000000000000000000000000E7\r
+S315600003B000000000000000000000000000000000D7\r
+S315600003C000000000000000000000000000000000C7\r
+S315600003D000000000000000000000000000000000B7\r
+S315600003E000000000000000000000000000000000A7\r
+S315600003F00000000000000000000000000000000097\r
+S315600004000000000000000000000000000000000086\r
+S315600004100000000000000000000000000000000076\r
+S315600004200000000000000000000000000000000066\r
+S315600004300000000000000000000000000000000056\r
+S315600004400000000000000000000000000000000046\r
+S315600004500000000000000000000000000000000036\r
+S315600004600000000000000000000000000000000026\r
+S315600004700000000000000000000000000000000016\r
+S315600004800000000000000000000000000000000006\r
+S3156000049000000000000000000000000000000000F6\r
+S315600004A000000000000000000000000000000000E6\r
+S315600004B000000000000000000000000000000000D6\r
+S315600004C000000000000000000000000000000000C6\r
+S315600004D000000000000000000000000000000000B6\r
+S315600004E000000000000000000000000000000000A6\r
+S315600004F00000000000000000000000000000000096\r
+S315600005000000000000000000000000000000000085\r
+S315600005100000000000000000000000000000000075\r
+S315600005200000000000000000000000000000000065\r
+S315600005300000000000000000000000000000000055\r
+S315600005400000000000000000000000000000000045\r
+S315600005500000000000000000000000000000000035\r
+S315600005600000000000000000000000000000000025\r
+S315600005700000000000000000000000000000000015\r
+S315600005800000000000000000000000000000000005\r
+S3156000059000000000000000000000000000000000F5\r
+S315600005A000000000000000000000000000000000E5\r
+S315600005B000000000000000000000000000000000D5\r
+S315600005C000000000000000000000000000000000C5\r
+S315600005D000000000000000000000000000000000B5\r
+S315600005E000000000000000000000000000000000A5\r
+S315600005F00000000000000000000000000000000095\r
+S315600006000000000000000000000000000000000084\r
+S315600006100000000000000000000000000000000074\r
+S315600006200000000000000000000000000000000064\r
+S315600006300000000000000000000000000000000054\r
+S315600006400000000000000000000000000000000044\r
+S315600006500000000000000000000000000000000034\r
+S315600006600000000000000000000000000000000024\r
+S315600006700000000000000000000000000000000014\r
+S315600006800000000000000000000000000000000004\r
+S3156000069000000000000000000000000000000000F4\r
+S315600006A000000000000000000000000000000000E4\r
+S315600006B000000000000000000000000000000000D4\r
+S315600006C000000000000000000000000000000000C4\r
+S315600006D000000000000000000000000000000000B4\r
+S315600006E000000000000000000000000000000000A4\r
+S315600006F00000000000000000000000000000000094\r
+S315600007000000000000000000000000000000000083\r
+S315600007100000000000000000000000000000000073\r
+S315600007200000000000000000000000000000000063\r
+S315600007300000000000000000000000000000000053\r
+S315600007400000000000000000000000000000000043\r
+S315600007500000000000000000000000000000000033\r
+S315600007600000000000000000000000000000000023\r
+S315600007700000000000000000000000000000000013\r
+S315600007800000000000000000000000000000000003\r
+S3156000079000000000000000000000000000000000F3\r
+S315600007A000000000000000000000000000000000E3\r
+S315600007B000000000000000000000000000000000D3\r
+S315600007C000000000000000000000000000000000C3\r
+S315600007D000000000000000000000000000000000B3\r
+S315600007E000000000000000000000000000000000A3\r
+S315600007F00000000000000000000000000000000093\r
+S315600008000000000000000000000000000000000082\r
+S315600008100000000000000000000000000000000072\r
+S315600008200000000000000000000000000000000062\r
+S315600008300000000000000000000000000000000052\r
+S315600008400000000000000000000000000000000042\r
+S315600008500000000000000000000000000000000032\r
+S315600008600000000000000000000000000000000022\r
+S315600008700000000000000000000000000000000012\r
+S315600008800000000000000000000000000000000002\r
+S3156000089000000000000000000000000000000000F2\r
+S315600008A000000000000000000000000000000000E2\r
+S315600008B000000000000000000000000000000000D2\r
+S315600008C000000000000000000000000000000000C2\r
+S315600008D000000000000000000000000000000000B2\r
+S315600008E000000000000000000000000000000000A2\r
+S315600008F00000000000000000000000000000000092\r
+S315600009000000000000000000000000000000000081\r
+S315600009100000000000000000000000000000000071\r
+S315600009200000000000000000000000000000000061\r
+S315600009300000000000000000000000000000000051\r
+S315600009400000000000000000000000000000000041\r
+S315600009500000000000000000000000000000000031\r
+S315600009600000000000000000000000000000000021\r
+S315600009700000000000000000000000000000000011\r
+S315600009800000000000000000000000000000000001\r
+S3156000099000000000000000000000000000000000F1\r
+S315600009A000000000000000000000000000000000E1\r
+S315600009B000000000000000000000000000000000D1\r
+S315600009C000000000000000000000000000000000C1\r
+S315600009D000000000000000000000000000000000B1\r
+S315600009E000000000000000000000000000000000A1\r
+S315600009F00000000000000000000000000000000091\r
+S31560000A000000000000000000000000000000000080\r
+S31560000A100000000000000000000000000000000070\r
+S31560000A200000000000000000000000000000000060\r
+S31560000A300000000000000000000000000000000050\r
+S31560000A400000000000000000000000000000000040\r
+S31560000A500000000000000000000000000000000030\r
+S31560000A600000000000000000000000000000000020\r
+S31560000A700000000000000000000000000000000010\r
+S31560000A800000000000000000000000000000000000\r
+S31560000A9000000000000000000000000000000000F0\r
+S31560000AA000000000000000000000000000000000E0\r
+S31560000AB000000000000000000000000000000000D0\r
+S31560000AC000000000000000000000000000000000C0\r
+S31560000AD000000000000000000000000000000000B0\r
+S31560000AE000000000000000000000000000000000A0\r
+S31560000AF00000000000000000000000000000000090\r
+S31560000B00000000000000000000000000000000007F\r
+S31560000B10000000000000000000000000000000006F\r
+S31560000B20000000000000000000000000000000005F\r
+S31560000B30000000000000000000000000000000004F\r
+S31560000B40000000000000000000000000000000003F\r
+S31560000B50000000000000000000000000000000002F\r
+S31560000B60000000000000000000000000000000001F\r
+S31560000B70000000000000000000000000000000000F\r
+S31560000B8000000000000000000000000000000000FF\r
+S31560000B9000000000000000000000000000000000EF\r
+S31560000BA000000000000000000000000000000000DF\r
+S31560000BB000000000000000000000000000000000CF\r
+S31560000BC000000000000000000000000000000000BF\r
+S31560000BD000000000000000000000000000000000AF\r
+S31560000BE0000000000000000000000000000000009F\r
+S31560000BF0000000000000000000000000000000008F\r
+S31560000C00000000000000000000000000000000007E\r
+S31560000C10000000000000000000000000000000006E\r
+S31560000C20000000000000000000000000000000005E\r
+S31560000C30000000000000000000000000000000004E\r
+S31560000C40000000000000000000000000000000003E\r
+S31560000C50000000000000000000000000000000002E\r
+S31560000C60000000000000000000000000000000001E\r
+S31560000C70000000000000000000000000000000000E\r
+S31560000C8000000000000000000000000000000000FE\r
+S31560000C9000000000000000000000000000000000EE\r
+S31560000CA000000000000000000000000000000000DE\r
+S31560000CB000000000000000000000000000000000CE\r
+S31560000CC000000000000000000000000000000000BE\r
+S31560000CD000000000000000000000000000000000AE\r
+S31560000CE0000000000000000000000000000000009E\r
+S31560000CF0000000000000000000000000000000008E\r
+S31560000D00000000000000000000000000000000007D\r
+S31560000D10000000000000000000000000000000006D\r
+S31560000D20000000000000000000000000000000005D\r
+S31560000D30000000000000000000000000000000004D\r
+S31560000D40000000000000000000000000000000003D\r
+S31560000D50000000000000000000000000000000002D\r
+S31560000D60000000000000000000000000000000001D\r
+S31560000D70000000000000000000000000000000000D\r
+S31560000D8000000000000000000000000000000000FD\r
+S31560000D9000000000000000000000000000000000ED\r
+S31560000DA000000000000000000000000000000000DD\r
+S31560000DB000000000000000000000000000000000CD\r
+S31560000DC000000000000000000000000000000000BD\r
+S31560000DD000000000000000000000000000000000AD\r
+S31560000DE0000000000000000000000000000000009D\r
+S31560000DF0000000000000000000000000000000008D\r
+S31560000E00000000000000000000000000000000007C\r
+S31560000E10000000000000000000000000000000006C\r
+S31560000E20000000000000000000000000000000005C\r
+S31560000E30000000000000000000000000000000004C\r
+S31560000E40000000000000000000000000000000003C\r
+S31560000E50000000000000000000000000000000002C\r
+S31560000E60000000000000000000000000000000001C\r
+S31560000E70000000000000000000000000000000000C\r
+S31560000E8000000000000000000000000000000000FC\r
+S31560000E9000000000000000000000000000000000EC\r
+S31560000EA000000000000000000000000000000000DC\r
+S31560000EB000000000000000000000000000000000CC\r
+S31560000EC000000000000000000000000000000000BC\r
+S31560000ED000000000000000000000000000000000AC\r
+S31560000EE0000000000000000000000000000000009C\r
+S31560000EF0000000000000000000000000000000008C\r
+S31560000F00000000000000000000000000000000007B\r
+S31560000F10000000000000000000000000000000006B\r
+S31560000F20000000000000000000000000000000005B\r
+S31560000F30000000000000000000000000000000004B\r
+S31560000F40000000000000000000000000000000003B\r
+S31560000F50000000000000000000000000000000002B\r
+S31560000F60000000000000000000000000000000001B\r
+S31560000F70000000000000000000000000000000000B\r
+S31560000F8000000000000000000000000000000000FB\r
+S31560000F9000000000000000000000000000000000EB\r
+S31560000FA000000000000000000000000000000000DB\r
+S31560000FB000000000000000000000000000000000CB\r
+S31560000FC000000000000000000000000000000000BB\r
+S31560000FD000000000000000000000000000000000AB\r
+S31560000FE0000000000000000000000000000000009B\r
+S31560000FF0000000000000000000000000000000008B\r
+S31560001000000000000000000000000000000000007A\r
+S31560001010000000000000000000000000000000006A\r
+S31560001020000000000000000000000000000000005A\r
+S31560001030000000000000000000000000000000004A\r
+S31560001040000000000000000000000000000000003A\r
+S31560001050000000000000000000000000000000002A\r
+S31560001060000000000000000000000000000000001A\r
+S31560001070000000000000000000000000000000000A\r
+S3156000108000000000000000000000000000000000FA\r
+S3156000109000000000000000000000000000000000EA\r
+S315600010A000000000000000000000000000000000DA\r
+S315600010B000000000000000000000000000000000CA\r
+S315600010C000000000000000000000000000000000BA\r
+S315600010D000000000000000000000000000000000AA\r
+S315600010E0000000000000000000000000000000009A\r
+S315600010F0000000000000000000000000000000008A\r
+S315600011000000000000000000000000000000000079\r
+S315600011100000000000000000000000000000000069\r
+S315600011200000000000000000000000000000000059\r
+S315600011300000000000000000000000000000000049\r
+S315600011400000000000000000000000000000000039\r
+S315600011500000000000000000000000000000000029\r
+S315600011600000000000000000000000000000000019\r
+S315600011700000000000000000000000000000000009\r
+S3156000118000000000000000000000000000000000F9\r
+S3156000119000000000000000000000000000000000E9\r
+S315600011A000000000000000000000000000000000D9\r
+S315600011B000000000000000000000000000000000C9\r
+S315600011C000000000000000000000000000000000B9\r
+S315600011D000000000000000000000000000000000A9\r
+S315600011E00000000000000000000000000000000099\r
+S315600011F00000000000000000000000000000000089\r
+S315600012000000000000000000000000000000000078\r
+S315600012100000000000000000000000000000000068\r
+S315600012200000000000000000000000000000000058\r
+S315600012300000000000000000000000000000000048\r
+S315600012400000000000000000000000000000000038\r
+S315600012500000000000000000000000000000000028\r
+S315600012600000000000000000000000000000000018\r
+S315600012700000000000000000000000000000000008\r
+S3156000128000000000000000000000000000000000F8\r
+S3156000129000000000000000000000000000000000E8\r
+S315600012A000000000000000000000000000000000D8\r
+S315600012B000000000000000000000000000000000C8\r
+S315600012C000000000000000000000000000000000B8\r
+S315600012D000000000000000000000000000000000A8\r
+S315600012E00000000000000000000000000000000098\r
+S315600012F00000000000000000000000000000000088\r
+S315600013000000000000000000000000000000000077\r
+S315600013100000000000000000000000000000000067\r
+S315600013200000000000000000000000000000000057\r
+S315600013300000000000000000000000000000000047\r
+S315600013400000000000000000000000000000000037\r
+S315600013500000000000000000000000000000000027\r
+S315600013600000000000000000000000000000000017\r
+S315600013700000000000000000000000000000000007\r
+S3156000138000000000000000000000000000000000F7\r
+S3156000139000000000000000000000000000000000E7\r
+S315600013A000000000000000000000000000000000D7\r
+S315600013B000000000000000000000000000000000C7\r
+S315600013C000000000000000000000000000000000B7\r
+S315600013D000000000000000000000000000000000A7\r
+S315600013E00000000000000000000000000000000097\r
+S315600013F00000000000000000000000000000000087\r
+S315600014000000000000000000000000000000000076\r
+S315600014100000000000000000000000000000000066\r
+S315600014200000000000000000000000000000000056\r
+S315600014300000000000000000000000000000000046\r
+S315600014400000000000000000000000000000000036\r
+S315600014500000000000000000000000000000000026\r
+S315600014600000000000000000000000000000000016\r
+S315600014700000000000000000000000000000000006\r
+S3156000148000000000000000000000000000000000F6\r
+S3156000149000000000000000000000000000000000E6\r
+S315600014A000000000000000000000000000000000D6\r
+S315600014B000000000000000000000000000000000C6\r
+S315600014C000000000000000000000000000000000B6\r
+S315600014D000000000000000000000000000000000A6\r
+S315600014E00000000000000000000000000000000096\r
+S315600014F00000000000000000000000000000000086\r
+S315600015000000000000000000000000000000000075\r
+S315600015100000000000000000000000000000000065\r
+S315600015200000000000000000000000000000000055\r
+S315600015300000000000000000000000000000000045\r
+S315600015400000000000000000000000000000000035\r
+S315600015500000000000000000000000000000000025\r
+S315600015600000000000000000000000000000000015\r
+S315600015700000000000000000000000000000000005\r
+S3156000158000000000000000000000000000000000F5\r
+S3156000159000000000000000000000000000000000E5\r
+S315600015A000000000000000000000000000000000D5\r
+S315600015B000000000000000000000000000000000C5\r
+S315600015C000000000000000000000000000000000B5\r
+S315600015D000000000000000000000000000000000A5\r
+S315600015E00000000000000000000000000000000095\r
+S315600015F00000000000000000000000000000000085\r
+S315600016000000000000000000000000000000000074\r
+S315600016100000000000000000000000000000000064\r
+S315600016200000000000000000000000000000000054\r
+S315600016300000000000000000000000000000000044\r
+S315600016400000000000000000000000000000000034\r
+S315600016500000000000000000000000000000000024\r
+S315600016600000000000000000000000000000000014\r
+S315600016700000000000000000000000000000000004\r
+S3156000168000000000000000000000000000000000F4\r
+S3156000169000000000000000000000000000000000E4\r
+S315600016A000000000000000000000000000000000D4\r
+S315600016B000000000000000000000000000000000C4\r
+S315600016C000000000000000000000000000000000B4\r
+S315600016D000000000000000000000000000000000A4\r
+S315600016E00000000000000000000000000000000094\r
+S315600016F00000000000000000000000000000000084\r
+S315600017000000000000000000000000000000000073\r
+S315600017100000000000000000000000000000000063\r
+S315600017200000000000000000000000000000000053\r
+S315600017300000000000000000000000000000000043\r
+S315600017400000000000000000000000000000000033\r
+S315600017500000000000000000000000000000000023\r
+S315600017600000000000000000000000000000000013\r
+S315600017700000000000000000000000000000000003\r
+S3156000178000000000000000000000000000000000F3\r
+S3156000179000000000000000000000000000000000E3\r
+S315600017A000000000000000000000000000000000D3\r
+S315600017B000000000000000000000000000000000C3\r
+S315600017C000000000000000000000000000000000B3\r
+S315600017D000000000000000000000000000000000A3\r
+S315600017E00000000000000000000000000000000093\r
+S315600017F00000000000000000000000000000000083\r
+S315600018000000000000000000000000000000000072\r
+S315600018100000000000000000000000000000000062\r
+S315600018200000000000000000000000000000000052\r
+S315600018300000000000000000000000000000000042\r
+S315600018400000000000000000000000000000000032\r
+S315600018500000000000000000000000000000000022\r
+S315600018600000000000000000000000000000000012\r
+S315600018700000000000000000000000000000000002\r
+S3156000188000000000000000000000000000000000F2\r
+S3156000189000000000000000000000000000000000E2\r
+S315600018A000000000000000000000000000000000D2\r
+S315600018B000000000000000000000000000000000C2\r
+S315600018C000000000000000000000000000000000B2\r
+S315600018D000000000000000000000000000000000A2\r
+S315600018E00000000000000000000000000000000092\r
+S315600018F00000000000000000000000000000000082\r
+S315600019000000000000000000000000000000000071\r
+S315600019100000000000000000000000000000000061\r
+S315600019200000000000000000000000000000000051\r
+S315600019300000000000000000000000000000000041\r
+S315600019400000000000000000000000000000000031\r
+S315600019500000000000000000000000000000000021\r
+S315600019600000000000000000000000000000000011\r
+S315600019700000000000000000000000000000000001\r
+S3156000198000000000000000000000000000000000F1\r
+S3156000199000000000000000000000000000000000E1\r
+S315600019A000000000000000000000000000000000D1\r
+S315600019B000000000000000000000000000000000C1\r
+S315600019C000000000000000000000000000000000B1\r
+S315600019D000000000000000000000000000000000A1\r
+S315600019E00000000000000000000000000000000091\r
+S315600019F00000000000000000000000000000000081\r
+S31560001A000000000000000000000000000000000070\r
+S31560001A100000000000000000000000000000000060\r
+S31560001A200000000000000000000000000000000050\r
+S31560001A300000000000000000000000000000000040\r
+S31560001A400000000000000000000000000000000030\r
+S31560001A500000000000000000000000000000000020\r
+S31560001A600000000000000000000000000000000010\r
+S31560001A700000000000000000000000000000000000\r
+S31560001A8000000000000000000000000000000000F0\r
+S31560001A9000000000000000000000000000000000E0\r
+S31560001AA000000000000000000000000000000000D0\r
+S31560001AB000000000000000000000000000000000C0\r
+S31560001AC000000000000000000000000000000000B0\r
+S31560001AD000000000000000000000000000000000A0\r
+S31560001AE00000000000000000000000000000000090\r
+S31560001AF00000000000000000000000000000000080\r
+S31560001B00000000000000000000000000000000006F\r
+S31560001B10000000000000000000000000000000005F\r
+S31560001B20000000000000000000000000000000004F\r
+S31560001B30000000000000000000000000000000003F\r
+S31560001B40000000000000000000000000000000002F\r
+S31560001B50000000000000000000000000000000001F\r
+S31560001B60000000000000000000000000000000000F\r
+S31560001B7000000000000000000000000000000000FF\r
+S31560001B8000000000000000000000000000000000EF\r
+S31560001B9000000000000000000000000000000000DF\r
+S31560001BA000000000000000000000000000000000CF\r
+S31560001BB000000000000000000000000000000000BF\r
+S31560001BC000000000000000000000000000000000AF\r
+S31560001BD0000000000000000000000000000000009F\r
+S31560001BE0000000000000000000000000000000008F\r
+S31560001BF0000000000000000000000000000000007F\r
+S31560001C00000000000000000000000000000000006E\r
+S31560001C10000000000000000000000000000000005E\r
+S31560001C20000000000000000000000000000000004E\r
+S31560001C30000000000000000000000000000000003E\r
+S31560001C40000000000000000000000000000000002E\r
+S31560001C50000000000000000000000000000000001E\r
+S31560001C60000000000000000000000000000000000E\r
+S31560001C7000000000000000000000000000000000FE\r
+S31560001C8000000000000000000000000000000000EE\r
+S31560001C9000000000000000000000000000000000DE\r
+S31560001CA000000000000000000000000000000000CE\r
+S31560001CB000000000000000000000000000000000BE\r
+S31560001CC000000000000000000000000000000000AE\r
+S31560001CD0000000000000000000000000000000009E\r
+S31560001CE0000000000000000000000000000000008E\r
+S31560001CF0000000000000000000000000000000007E\r
+S31560001D00000000000000000000000000000000006D\r
+S31560001D10000000000000000000000000000000005D\r
+S31560001D20000000000000000000000000000000004D\r
+S31560001D30000000000000000000000000000000003D\r
+S31560001D40000000000000000000000000000000002D\r
+S31560001D50000000000000000000000000000000001D\r
+S31560001D60000000000000000000000000000000000D\r
+S31560001D7000000000000000000000000000000000FD\r
+S31560001D8000000000000000000000000000000000ED\r
+S31560001D9000000000000000000000000000000000DD\r
+S31560001DA000000000000000000000000000000000CD\r
+S31560001DB000000000000000000000000000000000BD\r
+S31560001DC000000000000000000000000000000000AD\r
+S31560001DD0000000000000000000000000000000009D\r
+S31560001DE0000000000000000000000000000000008D\r
+S31560001DF0000000000000000000000000000000007D\r
+S31560001E00000000000000000000000000000000006C\r
+S31560001E10000000000000000000000000000000005C\r
+S31560001E20000000000000000000000000000000004C\r
+S31560001E30000000000000000000000000000000003C\r
+S31560001E40000000000000000000000000000000002C\r
+S31560001E50000000000000000000000000000000001C\r
+S31560001E60000000000000000000000000000000000C\r
+S31560001E7000000000000000000000000000000000FC\r
+S31560001E8000000000000000000000000000000000EC\r
+S31560001E9000000000000000000000000000000000DC\r
+S31560001EA000000000000000000000000000000000CC\r
+S31560001EB000000000000000000000000000000000BC\r
+S31560001EC000000000000000000000000000000000AC\r
+S31560001ED0000000000000000000000000000000009C\r
+S31560001EE0000000000000000000000000000000008C\r
+S31560001EF0000000000000000000000000000000007C\r
+S31560001F00000000000000000000000000000000006B\r
+S31560001F10000000000000000000000000000000005B\r
+S31560001F20000000000000000000000000000000004B\r
+S31560001F30000000000000000000000000000000003B\r
+S31560001F40000000000000000000000000000000002B\r
+S31560001F50000000000000000000000000000000001B\r
+S31560001F60000000000000000000000000000000000B\r
+S31560001F7000000000000000000000000000000000FB\r
+S31560001F8000000000000000000000000000000000EB\r
+S31560001F9000000000000000000000000000000000DB\r
+S31560001FA000000000000000000000000000000000CB\r
+S31560001FB000000000000000000000000000000000BB\r
+S31560001FC000000000000000000000000000000000AB\r
+S31560001FD0000000000000000000000000000000009B\r
+S31560001FE0000000000000000000000000000000008B\r
+S31560001FF0000000000000000000000000000000007B\r
+S31560002000000000000000000000000000000000006A\r
+S31560002010000000000000000000000000000000005A\r
+S31560002020000000000000000000000000000000004A\r
+S31560002030000000000000000000000000000000003A\r
+S31560002040000000000000000000000000000000002A\r
+S31560002050000000000000000000000000000000001A\r
+S31560002060000000000000000000000000000000000A\r
+S3156000207000000000000000000000000000000000FA\r
+S3156000208000000000000000000000000000000000EA\r
+S3156000209000000000000000000000000000000000DA\r
+S315600020A000000000000000000000000000000000CA\r
+S315600020B000000000000000000000000000000000BA\r
+S315600020C000000000000000000000000000000000AA\r
+S315600020D0000000000000000000000000000000009A\r
+S315600020E0000000000000000000000000000000008A\r
+S315600020F0000000000000000000000000000000007A\r
+S315600021000000000000000000000000000000000069\r
+S315600021100000000000000000000000000000000059\r
+S315600021200000000000000000000000000000000049\r
+S315600021300000000000000000000000000000000039\r
+S315600021400000000000000000000000000000000029\r
+S315600021500000000000000000000000000000000019\r
+S315600021600000000000000000000000000000000009\r
+S3156000217000000000000000000000000000000000F9\r
+S3156000218000000000000000000000000000000000E9\r
+S3156000219000000000000000000000000000000000D9\r
+S315600021A000000000000000000000000000000000C9\r
+S315600021B000000000000000000000000000000000B9\r
+S315600021C000000000000000000000000000000000A9\r
+S315600021D00000000000000000000000000000000099\r
+S315600021E00000000000000000000000000000000089\r
+S315600021F00000000000000000000000000000000079\r
+S315600022000000000000000000000000000000000068\r
+S315600022100000000000000000000000000000000058\r
+S315600022200000000000000000000000000000000048\r
+S315600022300000000000000000000000000000000038\r
+S315600022400000000000000000000000000000000028\r
+S315600022500000000000000000000000000000000018\r
+S315600022600000000000000000000000000000000008\r
+S3156000227000000000000000000000000000000000F8\r
+S3156000228000000000000000000000000000000000E8\r
+S3156000229000000000000000000000000000000000D8\r
+S315600022A000000000000000000000000000000000C8\r
+S315600022B000000000000000000000000000000000B8\r
+S315600022C000000000000000000000000000000000A8\r
+S315600022D00000000000000000000000000000000098\r
+S315600022E00000000000000000000000000000000088\r
+S315600022F00000000000000000000000000000000078\r
+S315600023000000000000000000000000000000000067\r
+S315600023100000000000000000000000000000000057\r
+S315600023200000000000000000000000000000000047\r
+S315600023300000000000000000000000000000000037\r
+S315600023400000000000000000000000000000000027\r
+S315600023500000000000000000000000000000000017\r
+S315600023600000000000000000000000000000000007\r
+S3156000237000000000000000000000000000000000F7\r
+S3156000238000000000000000000000000000000000E7\r
+S3156000239000000000000000000000000000000000D7\r
+S315600023A000000000000000000000000000000000C7\r
+S315600023B000000000000000000000000000000000B7\r
+S315600023C000000000000000000000000000000000A7\r
+S315600023D00000000000000000000000000000000097\r
+S315600023E00000000000000000000000000000000087\r
+S315600023F00000000000000000000000000000000077\r
+S315600024000000000000000000000000000000000066\r
+S315600024100000000000000000000000000000000056\r
+S315600024200000000000000000000000000000000046\r
+S315600024300000000000000000000000000000000036\r
+S315600024400000000000000000000000000000000026\r
+S315600024500000000000000000000000000000000016\r
+S315600024600000000000000000000000000000000006\r
+S3156000247000000000000000000000000000000000F6\r
+S3156000248000000000000000000000000000000000E6\r
+S3156000249000000000000000000000000000000000D6\r
+S315600024A000000000000000000000000000000000C6\r
+S315600024B000000000000000000000000000000000B6\r
+S315600024C000000000000000000000000000000000A6\r
+S315600024D00000000000000000000000000000000096\r
+S315600024E00000000000000000000000000000000086\r
+S315600024F00000000000000000000000000000000076\r
+S315600025000000000000000000000000000000000065\r
+S315600025100000000000000000000000000000000055\r
+S315600025200000000000000000000000000000000045\r
+S315600025300000000000000000000000000000000035\r
+S315600025400000000000000000000000000000000025\r
+S315600025500000000000000000000000000000000015\r
+S315600025600000000000000000000000000000000005\r
+S3156000257000000000000000000000000000000000F5\r
+S3156000258000000000000000000000000000000000E5\r
+S3156000259000000000000000000000000000000000D5\r
+S315600025A000000000000000000000000000000000C5\r
+S315600025B000000000000000000000000000000000B5\r
+S315600025C000000000000000000000000000000000A5\r
+S315600025D00000000000000000000000000000000095\r
+S315600025E00000000000000000000000000000000085\r
+S315600025F00000000000000000000000000000000075\r
+S315600026000000000000000000000000000000000064\r
+S315600026100000000000000000000000000000000054\r
+S315600026200000000000000000000000000000000044\r
+S315600026300000000000000000000000000000000034\r
+S315600026400000000000000000000000000000000024\r
+S315600026500000000000000000000000000000000014\r
+S315600026600000000000000000000000000000000004\r
+S3156000267000000000000000000000000000000000F4\r
+S3156000268000000000000000000000000000000000E4\r
+S3156000269000000000000000000000000000000000D4\r
+S315600026A000000000000000000000000000000000C4\r
+S315600026B000000000000000000000000000000000B4\r
+S315600026C000000000000000000000000000000000A4\r
+S315600026D00000000000000000000000000000000094\r
+S315600026E00000000000000000000000000000000084\r
+S315600026F00000000000000000000000000000000074\r
+S315600027000000000000000000000000000000000063\r
+S315600027100000000000000000000000000000000053\r
+S315600027200000000000000000000000000000000043\r
+S315600027300000000000000000000000000000000033\r
+S315600027400000000000000000000000000000000023\r
+S315600027500000000000000000000000000000000013\r
+S315600027600000000000000000000000000000000003\r
+S3156000277000000000000000000000000000000000F3\r
+S3156000278000000000000000000000000000000000E3\r
+S3156000279000000000000000000000000000000000D3\r
+S315600027A000000000000000000000000000000000C3\r
+S315600027B000000000000000000000000000000000B3\r
+S315600027C000000000000000000000000000000000A3\r
+S315600027D00000000000000000000000000000000093\r
+S315600027E00000000000000000000000000000000083\r
+S315600027F00000000000000000000000000000000073\r
+S315600028000000000000000000000000000000000062\r
+S315600028100000000000000000000000000000000052\r
+S315600028200000000000000000000000000000000042\r
+S315600028300000000000000000000000000000000032\r
+S315600028400000000000000000000000000000000022\r
+S315600028500000000000000000000000000000000012\r
+S315600028600000000000000000000000000000000002\r
+S3156000287000000000000000000000000000000000F2\r
+S3156000288000000000000000000000000000000000E2\r
+S3156000289000000000000000000000000000000000D2\r
+S315600028A000000000000000000000000000000000C2\r
+S315600028B000000000000000000000000000000000B2\r
+S315600028C000000000000000000000000000000000A2\r
+S315600028D00000000000000000000000000000000092\r
+S315600028E00000000000000000000000000000000082\r
+S315600028F00000000000000000000000000000000072\r
+S315600029000000000000000000000000000000000061\r
+S315600029100000000000000000000000000000000051\r
+S315600029200000000000000000000000000000000041\r
+S315600029300000000000000000000000000000000031\r
+S315600029400000000000000000000000000000000021\r
+S315600029500000000000000000000000000000000011\r
+S315600029600000000000000000000000000000000001\r
+S3156000297000000000000000000000000000000000F1\r
+S3156000298000000000000000000000000000000000E1\r
+S3156000299000000000000000000000000000000000D1\r
+S315600029A000000000000000000000000000000000C1\r
+S315600029B000000000000000000000000000000000B1\r
+S315600029C000000000000000000000000000000000A1\r
+S315600029D00000000000000000000000000000000091\r
+S315600029E00000000000000000000000000000000081\r
+S315600029F00000000000000000000000000000000071\r
+S31560002A000000000000000000000000000000000060\r
+S31560002A100000000000000000000000000000000050\r
+S31560002A200000000000000000000000000000000040\r
+S31560002A300000000000000000000000000000000030\r
+S31560002A400000000000000000000000000000000020\r
+S31560002A500000000000000000000000000000000010\r
+S31560002A600000000000000000000000000000000000\r
+S31560002A7000000000000000000000000000000000F0\r
+S31560002A8000000000000000000000000000000000E0\r
+S31560002A9000000000000000000000000000000000D0\r
+S31560002AA000000000000000000000000000000000C0\r
+S31560002AB000000000000000000000000000000000B0\r
+S31560002AC000000000000000000000000000000000A0\r
+S31560002AD00000000000000000000000000000000090\r
+S31560002AE00000000000000000000000000000000080\r
+S31560002AF00000000000000000000000000000000070\r
+S31560002B00000000000000000000000000000000005F\r
+S31560002B10000000000000000000000000000000004F\r
+S31560002B20000000000000000000000000000000003F\r
+S31560002B30000000000000000000000000000000002F\r
+S31560002B40000000000000000000000000000000001F\r
+S31560002B50000000000000000000000000000000000F\r
+S31560002B6000000000000000000000000000000000FF\r
+S31560002B7000000000000000000000000000000000EF\r
+S31560002B8000000000000000000000000000000000DF\r
+S31560002B9000000000000000000000000000000000CF\r
+S31560002BA000000000000000000000000000000000BF\r
+S31560002BB000000000000000000000000000000000AF\r
+S31560002BC0000000000000000000000000000000009F\r
+S31560002BD0000000000000000000000000000000008F\r
+S31560002BE0000000000000000000000000000000007F\r
+S31560002BF0000000000000000000000000000000006F\r
+S31560002C00000000000000000000000000000000005E\r
+S31560002C10000000000000000000000000000000004E\r
+S31560002C20000000000000000000000000000000003E\r
+S31560002C30000000000000000000000000000000002E\r
+S31560002C40000000000000000000000000000000001E\r
+S31560002C50000000000000000000000000000000000E\r
+S31560002C6000000000000000000000000000000000FE\r
+S31560002C7000000000000000000000000000000000EE\r
+S31560002C8000000000000000000000000000000000DE\r
+S31560002C9000000000000000000000000000000000CE\r
+S31560002CA000000000000000000000000000000000BE\r
+S31560002CB000000000000000000000000000000000AE\r
+S31560002CC0000000000000000000000000000000009E\r
+S31560002CD0000000000000000000000000000000008E\r
+S31560002CE0000000000000000000000000000000007E\r
+S31560002CF0000000000000000000000000000000006E\r
+S31560002D00000000000000000000000000000000005D\r
+S31560002D10000000000000000000000000000000004D\r
+S31560002D20000000000000000000000000000000003D\r
+S31560002D30000000000000000000000000000000002D\r
+S31560002D40000000000000000000000000000000001D\r
+S31560002D50000000000000000000000000000000000D\r
+S31560002D6000000000000000000000000000000000FD\r
+S31560002D7000000000000000000000000000000000ED\r
+S31560002D8000000000000000000000000000000000DD\r
+S31560002D9000000000000000000000000000000000CD\r
+S31560002DA000000000000000000000000000000000BD\r
+S31560002DB000000000000000000000000000000000AD\r
+S31560002DC0000000000000000000000000000000009D\r
+S31560002DD0000000000000000000000000000000008D\r
+S31560002DE0000000000000000000000000000000007D\r
+S31560002DF0000000000000000000000000000000006D\r
+S31560002E00000000000000000000000000000000005C\r
+S31560002E10000000000000000000000000000000004C\r
+S31560002E20000000000000000000000000000000003C\r
+S31560002E30000000000000000000000000000000002C\r
+S31560002E40000000000000000000000000000000001C\r
+S31560002E50000000000000000000000000000000000C\r
+S31560002E6000000000000000000000000000000000FC\r
+S31560002E7000000000000000000000000000000000EC\r
+S31560002E8000000000000000000000000000000000DC\r
+S31560002E9000000000000000000000000000000000CC\r
+S31560002EA000000000000000000000000000000000BC\r
+S31560002EB000000000000000000000000000000000AC\r
+S31560002EC0000000000000000000000000000000009C\r
+S31560002ED0000000000000000000000000000000008C\r
+S31560002EE0000000000000000000000000000000007C\r
+S31560002EF0000000000000000000000000000000006C\r
+S31560002F00000000000000000000000000000000005B\r
+S31560002F10000000000000000000000000000000004B\r
+S31560002F20000000000000000000000000000000003B\r
+S31560002F30000000000000000000000000000000002B\r
+S31560002F40000000000000000000000000000000001B\r
+S31560002F50000000000000000000000000000000000B\r
+S31560002F6000000000000000000000000000000000FB\r
+S31560002F7000000000000000000000000000000000EB\r
+S31560002F8000000000000000000000000000000000DB\r
+S31560002F9000000000000000000000000000000000CB\r
+S31560002FA000000000000000000000000000000000BB\r
+S31560002FB000000000000000000000000000000000AB\r
+S31560002FC0000000000000000000000000000000009B\r
+S31560002FD0000000000000000000000000000000008B\r
+S31560002FE0000000000000000000000000000000007B\r
+S31560002FF0000000000000000000000000000000006B\r
+S31560003000000000000000000000000000000000005A\r
+S31560003010000000000000000000000000000000004A\r
+S31560003020000000000000000000000000000000003A\r
+S31560003030000000000000000000000000000000002A\r
+S31560003040000000000000000000000000000000001A\r
+S31560003050000000000000000000000000000000000A\r
+S3156000306000000000000000000000000000000000FA\r
+S3156000307000000000000000000000000000000000EA\r
+S3156000308000000000000000000000000000000000DA\r
+S3156000309000000000000000000000000000000000CA\r
+S315600030A000000000000000000000000000000000BA\r
+S315600030B000000000000000000000000000000000AA\r
+S315600030C0000000000000000000000000000000009A\r
+S315600030D0000000000000000000000000000000008A\r
+S315600030E0000000000000000000000000000000007A\r
+S315600030F0000000000000000000000000000000006A\r
+S315600031000000000000000000000000000000000059\r
+S315600031100000000000000000000000000000000049\r
+S315600031200000000000000000000000000000000039\r
+S315600031300000000000000000000000000000000029\r
+S315600031400000000000000000000000000000000019\r
+S315600031500000000000000000000000000000000009\r
+S3156000316000000000000000000000000000000000F9\r
+S3156000317000000000000000000000000000000000E9\r
+S3156000318000000000000000000000000000000000D9\r
+S3156000319000000000000000000000000000000000C9\r
+S315600031A000000000000000000000000000000000B9\r
+S315600031B000000000000000000000000000000000A9\r
+S315600031C00000000000000000000000000000000099\r
+S315600031D00000000000000000000000000000000089\r
+S315600031E00000000000000000000000000000000079\r
+S315600031F00000000000000000000000000000000069\r
+S315600032000000000000000000000000000000000058\r
+S315600032100000000000000000000000000000000048\r
+S315600032200000000000000000000000000000000038\r
+S315600032300000000000000000000000000000000028\r
+S315600032400000000000000000000000000000000018\r
+S315600032500000000000000000000000000000000008\r
+S3156000326000000000000000000000000000000000F8\r
+S3156000327000000000000000000000000000000000E8\r
+S3156000328000000000000000000000000000000000D8\r
+S3156000329000000000000000000000000000000000C8\r
+S315600032A000000000000000000000000000000000B8\r
+S315600032B000000000000000000000000000000000A8\r
+S315600032C00000000000000000000000000000000098\r
+S315600032D00000000000000000000000000000000088\r
+S315600032E00000000000000000000000000000000078\r
+S315600032F00000000000000000000000000000000068\r
+S315600033000000000000000000000000000000000057\r
+S315600033100000000000000000000000000000000047\r
+S315600033200000000000000000000000000000000037\r
+S315600033300000000000000000000000000000000027\r
+S315600033400000000000000000000000000000000017\r
+S315600033500000000000000000000000000000000007\r
+S3156000336000000000000000000000000000000000F7\r
+S3156000337000000000000000000000000000000000E7\r
+S3156000338000000000000000000000000000000000D7\r
+S3156000339000000000000000000000000000000000C7\r
+S315600033A000000000000000000000000000000000B7\r
+S315600033B000000000000000000000000000000000A7\r
+S315600033C00000000000000000000000000000000097\r
+S315600033D00000000000000000000000000000000087\r
+S315600033E00000000000000000000000000000000077\r
+S315600033F00000000000000000000000000000000067\r
+S315600034000000000000000000000000000000000056\r
+S315600034100000000000000000000000000000000046\r
+S315600034200000000000000000000000000000000036\r
+S315600034300000000000000000000000000000000026\r
+S315600034400000000000000000000000000000000016\r
+S315600034500000000000000000000000000000000006\r
+S3156000346000000000000000000000000000000000F6\r
+S3156000347000000000000000000000000000000000E6\r
+S3156000348000000000000000000000000000000000D6\r
+S3156000349000000000000000000000000000000000C6\r
+S315600034A000000000000000000000000000000000B6\r
+S315600034B000000000000000000000000000000000A6\r
+S315600034C00000000000000000000000000000000096\r
+S315600034D00000000000000000000000000000000086\r
+S315600034E00000000000000000000000000000000076\r
+S315600034F00000000000000000000000000000000066\r
+S315600035000000000000000000000000000000000055\r
+S315600035100000000000000000000000000000000045\r
+S315600035200000000000000000000000000000000035\r
+S315600035300000000000000000000000000000000025\r
+S315600035400000000000000000000000000000000015\r
+S315600035500000000000000000000000000000000005\r
+S3156000356000000000000000000000000000000000F5\r
+S3156000357000000000000000000000000000000000E5\r
+S3156000358000000000000000000000000000000000D5\r
+S3156000359000000000000000000000000000000000C5\r
+S315600035A000000000000000000000000000000000B5\r
+S315600035B000000000000000000000000000000000A5\r
+S315600035C00000000000000000000000000000000095\r
+S315600035D00000000000000000000000000000000085\r
+S315600035E00000000000000000000000000000000075\r
+S315600035F00000000000000000000000000000000065\r
+S315600036000000000000000000000000000000000054\r
+S315600036100000000000000000000000000000000044\r
+S315600036200000000000000000000000000000000034\r
+S315600036300000000000000000000000000000000024\r
+S315600036400000000000000000000000000000000014\r
+S315600036500000000000000000000000000000000004\r
+S3156000366000000000000000000000000000000000F4\r
+S3156000367000000000000000000000000000000000E4\r
+S3156000368000000000000000000000000000000000D4\r
+S3156000369000000000000000000000000000000000C4\r
+S315600036A000000000000000000000000000000000B4\r
+S315600036B000000000000000000000000000000000A4\r
+S315600036C00000000000000000000000000000000094\r
+S315600036D00000000000000000000000000000000084\r
+S315600036E00000000000000000000000000000000074\r
+S315600036F00000000000000000000000000000000064\r
+S315600037000000000000000000000000000000000053\r
+S315600037100000000000000000000000000000000043\r
+S315600037200000000000000000000000000000000033\r
+S315600037300000000000000000000000000000000023\r
+S315600037400000000000000000000000000000000013\r
+S315600037500000000000000000000000000000000003\r
+S3156000376000000000000000000000000000000000F3\r
+S3156000377000000000000000000000000000000000E3\r
+S3156000378000000000000000000000000000000000D3\r
+S3156000379000000000000000000000000000000000C3\r
+S315600037A000000000000000000000000000000000B3\r
+S315600037B000000000000000000000000000000000A3\r
+S315600037C00000000000000000000000000000000093\r
+S315600037D00000000000000000000000000000000083\r
+S315600037E00000000000000000000000000000000073\r
+S315600037F00000000000000000000000000000000063\r
+S315600038000000000000000000000000000000000052\r
+S315600038100000000000000000000000000000000042\r
+S315600038200000000000000000000000000000000032\r
+S315600038300000000000000000000000000000000022\r
+S315600038400000000000000000000000000000000012\r
+S315600038500000000000000000000000000000000002\r
+S3156000386000000000000000000000000000000000F2\r
+S3156000387000000000000000000000000000000000E2\r
+S3156000388000000000000000000000000000000000D2\r
+S3156000389000000000000000000000000000000000C2\r
+S315600038A000000000000000000000000000000000B2\r
+S315600038B000000000000000000000000000000000A2\r
+S315600038C00000000000000000000000000000000092\r
+S315600038D00000000000000000000000000000000082\r
+S315600038E00000000000000000000000000000000072\r
+S315600038F00000000000000000000000000000000062\r
+S315600039000000000000000000000000000000000051\r
+S315600039100000000000000000000000000000000041\r
+S315600039200000000000000000000000000000000031\r
+S315600039300000000000000000000000000000000021\r
+S315600039400000000000000000000000000000000011\r
+S315600039500000000000000000000000000000000001\r
+S3156000396000000000000000000000000000000000F1\r
+S3156000397000000000000000000000000000000000E1\r
+S3156000398000000000000000000000000000000000D1\r
+S3156000399000000000000000000000000000000000C1\r
+S315600039A000000000000000000000000000000000B1\r
+S315600039B000000000000000000000000000000000A1\r
+S315600039C00000000000000000000000000000000091\r
+S315600039D00000000000000000000000000000000081\r
+S315600039E00000000000000000000000000000000071\r
+S315600039F00000000000000000000000000000000061\r
+S31560003A000000000000000000000000000000000050\r
+S31560003A100000000000000000000000000000000040\r
+S31560003A200000000000000000000000000000000030\r
+S31560003A300000000000000000000000000000000020\r
+S31560003A400000000000000000000000000000000010\r
+S31560003A500000000000000000000000000000000000\r
+S31560003A6000000000000000000000000000000000F0\r
+S31560003A7000000000000000000000000000000000E0\r
+S31560003A8000000000000000000000000000000000D0\r
+S31560003A9000000000000000000000000000000000C0\r
+S31560003AA000000000000000000000000000000000B0\r
+S31560003AB000000000000000000000000000000000A0\r
+S31560003AC00000000000000000000000000000000090\r
+S31560003AD00000000000000000000000000000000080\r
+S31560003AE00000000000000000000000000000000070\r
+S31560003AF00000000000000000000000000000000060\r
+S31560003B00000000000000000000000000000000004F\r
+S31560003B10000000000000000000000000000000003F\r
+S31560003B20000000000000000000000000000000002F\r
+S31560003B30000000000000000000000000000000001F\r
+S31560003B40000000000000000000000000000000000F\r
+S31560003B5000000000000000000000000000000000FF\r
+S31560003B6000000000000000000000000000000000EF\r
+S31560003B7000000000000000000000000000000000DF\r
+S31560003B8000000000000000000000000000000000CF\r
+S31560003B9000000000000000000000000000000000BF\r
+S31560003BA000000000000000000000000000000000AF\r
+S31560003BB0000000000000000000000000000000009F\r
+S31560003BC0000000000000000000000000000000008F\r
+S31560003BD0000000000000000000000000000000007F\r
+S31560003BE0000000000000000000000000000000006F\r
+S31560003BF0000000000000000000000000000000005F\r
+S31560003C00000000000000000000000000000000004E\r
+S31560003C10000000000000000000000000000000003E\r
+S31560003C20000000000000000000000000000000002E\r
+S31560003C30000000000000000000000000000000001E\r
+S31560003C40000000000000000000000000000000000E\r
+S31560003C5000000000000000000000000000000000FE\r
+S31560003C6000000000000000000000000000000000EE\r
+S31560003C7000000000000000000000000000000000DE\r
+S31560003C8000000000000000000000000000000000CE\r
+S31560003C9000000000000000000000000000000000BE\r
+S31560003CA000000000000000000000000000000000AE\r
+S31560003CB0000000000000000000000000000000009E\r
+S31560003CC0000000000000000000000000000000008E\r
+S31560003CD0000000000000000000000000000000007E\r
+S31560003CE0000000000000000000000000000000006E\r
+S31560003CF0000000000000000000000000000000005E\r
+S31560003D00000000000000000000000000000000004D\r
+S31560003D10000000000000000000000000000000003D\r
+S31560003D20000000000000000000000000000000002D\r
+S31560003D30000000000000000000000000000000001D\r
+S31560003D40000000000000000000000000000000000D\r
+S31560003D5000000000000000000000000000000000FD\r
+S31560003D6000000000000000000000000000000000ED\r
+S31560003D7000000000000000000000000000000000DD\r
+S31560003D8000000000000000000000000000000000CD\r
+S31560003D9000000000000000000000000000000000BD\r
+S31560003DA000000000000000000000000000000000AD\r
+S31560003DB0000000000000000000000000000000009D\r
+S31560003DC0000000000000000000000000000000008D\r
+S31560003DD0000000000000000000000000000000007D\r
+S31560003DE0000000000000000000000000000000006D\r
+S31560003DF0000000000000000000000000000000005D\r
+S31560003E00000000000000000000000000000000004C\r
+S31560003E10000000000000000000000000000000003C\r
+S31560003E20000000000000000000000000000000002C\r
+S31560003E30000000000000000000000000000000001C\r
+S31560003E40000000000000000000000000000000000C\r
+S31560003E5000000000000000000000000000000000FC\r
+S31560003E6000000000000000000000000000000000EC\r
+S31560003E7000000000000000000000000000000000DC\r
+S31560003E8000000000000000000000000000000000CC\r
+S31560003E9000000000000000000000000000000000BC\r
+S31560003EA000000000000000000000000000000000AC\r
+S31560003EB0000000000000000000000000000000009C\r
+S31560003EC0000000000000000000000000000000008C\r
+S31560003ED0000000000000000000000000000000007C\r
+S31560003EE0000000000000000000000000000000006C\r
+S31560003EF0000000000000000000000000000000005C\r
+S31560003F00000000000000000000000000000000004B\r
+S31560003F10000000000000000000000000000000003B\r
+S31560003F20000000000000000000000000000000002B\r
+S31560003F30000000000000000000000000000000001B\r
+S31560003F40000000000000000000000000000000000B\r
+S31560003F5000000000000000000000000000000000FB\r
+S31560003F6000000000000000000000000000000000EB\r
+S31560003F7000000000000000000000000000000000DB\r
+S31560003F8000000000000000000000000000000000CB\r
+S31560003F9000000000000000000000000000000000BB\r
+S31560003FA000000000000000000000000000000000AB\r
+S31560003FB0000000000000000000000000000000009B\r
+S31560003FC0000000000000000000000000000000008B\r
+S31560003FD0000000000000000000000000000000007B\r
+S31560003FE0000000000000000000000000000000006B\r
+S31560003FF0000000000000000000000000000000005B\r
+S31560004000000000000000000000000000000000004A\r
+S31560004010000000000000000000000000000000003A\r
+S31560004020000000000000000000000000000000002A\r
+S31560004030000000000000000000000000000000001A\r
+S31560004040000000000000000000000000000000000A\r
+S3156000405000000000000000000000000000000000FA\r
+S3156000406000000000000000000000000000000000EA\r
+S3156000407000000000000000000000000000000000DA\r
+S3156000408000000000000000000000000000000000CA\r
+S3156000409000000000000000000000000000000000BA\r
+S315600040A000000000000000000000000000000000AA\r
+S315600040B0000000000000000000000000000000009A\r
+S315600040C0000000000000000000000000000000008A\r
+S315600040D0000000000000000000000000000000007A\r
+S315600040E0000000000000000000000000000000006A\r
+S315600040F0000000000000000000000000000000005A\r
+S315600041000000000000000000000000000000000049\r
+S315600041100000000000000000000000000000000039\r
+S315600041200000000000000000000000000000000029\r
+S315600041300000000000000000000000000000000019\r
+S315600041400000000000000000000000000000000009\r
+S3156000415000000000000000000000000000000000F9\r
+S3156000416000000000000000000000000000000000E9\r
+S3156000417000000000000000000000000000000000D9\r
+S3156000418000000000000000000000000000000000C9\r
+S3156000419000000000000000000000000000000000B9\r
+S315600041A000000000000000000000000000000000A9\r
+S315600041B00000000000000000000000000000000099\r
+S315600041C00000000000000000000000000000000089\r
+S315600041D00000000000000000000000000000000079\r
+S315600041E00000000000000000000000000000000069\r
+S315600041F00000000000000000000000000000000059\r
+S315600042000000000000000000000000000000000048\r
+S315600042100000000000000000000000000000000038\r
+S315600042200000000000000000000000000000000028\r
+S315600042300000000000000000000000000000000018\r
+S315600042400000000000000000000000000000000008\r
+S3156000425000000000000000000000000000000000F8\r
+S3156000426000000000000000000000000000000000E8\r
+S3156000427000000000000000000000000000000000D8\r
+S3156000428000000000000000000000000000000000C8\r
+S3156000429000000000000000000000000000000000B8\r
+S315600042A000000000000000000000000000000000A8\r
+S315600042B00000000000000000000000000000000098\r
+S315600042C00000000000000000000000000000000088\r
+S315600042D00000000000000000000000000000000078\r
+S315600042E00000000000000000000000000000000068\r
+S315600042F00000000000000000000000000000000058\r
+S315600043000000000000000000000000000000000047\r
+S315600043100000000000000000000000000000000037\r
+S315600043200000000000000000000000000000000027\r
+S315600043300000000000000000000000000000000017\r
+S315600043400000000000000000000000000000000007\r
+S3156000435000000000000000000000000000000000F7\r
+S3156000436000000000000000000000000000000000E7\r
+S3156000437000000000000000000000000000000000D7\r
+S3156000438000000000000000000000000000000000C7\r
+S3156000439000000000000000000000000000000000B7\r
+S315600043A000000000000000000000000000000000A7\r
+S315600043B00000000000000000000000000000000097\r
+S315600043C00000000000000000000000000000000087\r
+S315600043D00000000000000000000000000000000077\r
+S315600043E00000000000000000000000000000000067\r
+S315600043F00000000000000000000000000000000057\r
+S315600044000000000000000000000000000000000046\r
+S315600044100000000000000000000000000000000036\r
+S315600044200000000000000000000000000000000026\r
+S315600044300000000000000000000000000000000016\r
+S315600044400000000000000000000000000000000006\r
+S3156000445000000000000000000000000000000000F6\r
+S3156000446000000000000000000000000000000000E6\r
+S3156000447000000000000000000000000000000000D6\r
+S3156000448000000000000000000000000000000000C6\r
+S3156000449000000000000000000000000000000000B6\r
+S315600044A000000000000000000000000000000000A6\r
+S315600044B00000000000000000000000000000000096\r
+S315600044C00000000000000000000000000000000086\r
+S315600044D00000000000000000000000000000000076\r
+S315600044E00000000000000000000000000000000066\r
+S315600044F00000000000000000000000000000000056\r
+S315600045000000000000000000000000000000000045\r
+S315600045100000000000000000000000000000000035\r
+S315600045200000000000000000000000000000000025\r
+S315600045300000000000000000000000000000000015\r
+S315600045400000000000000000000000000000000005\r
+S3156000455000000000000000000000000000000000F5\r
+S3156000456000000000000000000000000000000000E5\r
+S3156000457000000000000000000000000000000000D5\r
+S3156000458000000000000000000000000000000000C5\r
+S3156000459000000000000000000000000000000000B5\r
+S315600045A000000000000000000000000000000000A5\r
+S315600045B00000000000000000000000000000000095\r
+S315600045C00000000000000000000000000000000085\r
+S315600045D00000000000000000000000000000000075\r
+S315600045E00000000000000000000000000000000065\r
+S315600045F00000000000000000000000000000000055\r
+S315600046000000000000000000000000000000000044\r
+S315600046100000000000000000000000000000000034\r
+S315600046200000000000000000000000000000000024\r
+S315600046300000000000000000000000000000000014\r
+S315600046400000000000000000000000000000000004\r
+S3156000465000000000000000000000000000000000F4\r
+S3156000466000000000000000000000000000000000E4\r
+S3156000467000000000000000000000000000000000D4\r
+S3156000468000000000000000000000000000000000C4\r
+S3156000469000000000000000000000000000000000B4\r
+S315600046A000000000000000000000000000000000A4\r
+S315600046B00000000000000000000000000000000094\r
+S315600046C00000000000000000000000000000000084\r
+S315600046D00000000000000000000000000000000074\r
+S315600046E00000000000000000000000000000000064\r
+S315600046F00000000000000000000000000000000054\r
+S315600047000000000000000000000000000000000043\r
+S315600047100000000000000000000000000000000033\r
+S315600047200000000000000000000000000000000023\r
+S315600047300000000000000000000000000000000013\r
+S315600047400000000000000000000000000000000003\r
+S3156000475000000000000000000000000000000000F3\r
+S3156000476000000000000000000000000000000000E3\r
+S3156000477000000000000000000000000000000000D3\r
+S3156000478000000000000000000000000000000000C3\r
+S3156000479000000000000000000000000000000000B3\r
+S315600047A000000000000000000000000000000000A3\r
+S315600047B00000000000000000000000000000000093\r
+S315600047C00000000000000000000000000000000083\r
+S315600047D00000000000000000000000000000000073\r
+S315600047E00000000000000000000000000000000063\r
+S315600047F00000000000000000000000000000000053\r
+S315600048000000000000000000000000000000000042\r
+S315600048100000000000000000000000000000000032\r
+S315600048200000000000000000000000000000000022\r
+S315600048300000000000000000000000000000000012\r
+S315600048400000000000000000000000000000000002\r
+S3156000485000000000000000000000000000000000F2\r
+S3156000486000000000000000000000000000000000E2\r
+S3156000487000000000000000000000000000000000D2\r
+S3156000488000000000000000000000000000000000C2\r
+S3156000489000000000000000000000000000000000B2\r
+S315600048A000000000000000000000000000000000A2\r
+S315600048B00000000000000000000000000000000092\r
+S315600048C00000000000000000000000000000000082\r
+S315600048D00000000000000000000000000000000072\r
+S315600048E00000000000000000000000000000000062\r
+S315600048F00000000000000000000000000000000052\r
+S315600049000000000000000000000000000000000041\r
+S315600049100000000000000000000000000000000031\r
+S315600049200000000000000000000000000000000021\r
+S315600049300000000000000000000000000000000011\r
+S315600049400000000000000000000000000000000001\r
+S3156000495000000000000000000000000000000000F1\r
+S3156000496000000000000000000000000000000000E1\r
+S3156000497000000000000000000000000000000000D1\r
+S3156000498000000000000000000000000000000000C1\r
+S3156000499000000000000000000000000000000000B1\r
+S315600049A000000000000000000000000000000000A1\r
+S315600049B00000000000000000000000000000000091\r
+S315600049C00000000000000000000000000000000081\r
+S315600049D00000000000000000000000000000000071\r
+S315600049E00000000000000000000000000000000061\r
+S315600049F00000000000000000000000000000000051\r
+S31560004A000000000000000000000000000000000040\r
+S31560004A100000000000000000000000000000000030\r
+S31560004A200000000000000000000000000000000020\r
+S31560004A300000000000000000000000000000000010\r
+S31560004A400000000000000000000000000000000000\r
+S31560004A5000000000000000000000000000000000F0\r
+S31560004A6000000000000000000000000000000000E0\r
+S31560004A7000000000000000000000000000000000D0\r
+S31560004A8000000000000000000000000000000000C0\r
+S31560004A9000000000000000000000000000000000B0\r
+S31560004AA000000000000000000000000000000000A0\r
+S31560004AB00000000000000000000000000000000090\r
+S31560004AC00000000000000000000000000000000080\r
+S31560004AD00000000000000000000000000000000070\r
+S31560004AE00000000000000000000000000000000060\r
+S31560004AF00000000000000000000000000000000050\r
+S31560004B00000000000000000000000000000000003F\r
+S31560004B10000000000000000000000000000000002F\r
+S31560004B20000000000000000000000000000000001F\r
+S31560004B30000000000000000000000000000000000F\r
+S31560004B4000000000000000000000000000000000FF\r
+S31560004B5000000000000000000000000000000000EF\r
+S31560004B6000000000000000000000000000000000DF\r
+S31560004B7000000000000000000000000000000000CF\r
+S31560004B8000000000000000000000000000000000BF\r
+S31560004B9000000000000000000000000000000000AF\r
+S31560004BA0000000000000000000000000000000009F\r
+S31560004BB0000000000000000000000000000000008F\r
+S31560004BC0000000000000000000000000000000007F\r
+S31560004BD0000000000000000000000000000000006F\r
+S31560004BE0000000000000000000000000000000005F\r
+S31560004BF0000000000000000000000000000000004F\r
+S31560004C00000000000000000000000000000000003E\r
+S31560004C10000000000000000000000000000000002E\r
+S31560004C20000000000000000000000000000000001E\r
+S31560004C30000000000000000000000000000000000E\r
+S31560004C4000000000000000000000000000000000FE\r
+S31560004C5000000000000000000000000000000000EE\r
+S31560004C6000000000000000000000000000000000DE\r
+S31560004C7000000000000000000000000000000000CE\r
+S31560004C8000000000000000000000000000000000BE\r
+S31560004C9000000000000000000000000000000000AE\r
+S31560004CA0000000000000000000000000000000009E\r
+S31560004CB0000000000000000000000000000000008E\r
+S31560004CC0000000000000000000000000000000007E\r
+S31560004CD0000000000000000000000000000000006E\r
+S31560004CE0000000000000000000000000000000005E\r
+S31560004CF0000000000000000000000000000000004E\r
+S31560004D00000000000000000000000000000000003D\r
+S31560004D10000000000000000000000000000000002D\r
+S31560004D20000000000000000000000000000000001D\r
+S31560004D30000000000000000000000000000000000D\r
+S31560004D4000000000000000000000000000000000FD\r
+S31560004D5000000000000000000000000000000000ED\r
+S31560004D6000000000000000000000000000000000DD\r
+S31560004D7000000000000000000000000000000000CD\r
+S31560004D8000000000000000000000000000000000BD\r
+S31560004D9000000000000000000000000000000000AD\r
+S31560004DA0000000000000000000000000000000009D\r
+S31560004DB0000000000000000000000000000000008D\r
+S31560004DC0000000000000000000000000000000007D\r
+S31560004DD0000000000000000000000000000000006D\r
+S31560004DE0000000000000000000000000000000005D\r
+S31560004DF0000000000000000000000000000000004D\r
+S31560004E00000000000000000000000000000000003C\r
+S31560004E10000000000000000000000000000000002C\r
+S31560004E20000000000000000000000000000000001C\r
+S31560004E30000000000000000000000000000000000C\r
+S31560004E4000000000000000000000000000000000FC\r
+S31560004E5000000000000000000000000000000000EC\r
+S31560004E6000000000000000000000000000000000DC\r
+S31560004E7000000000000000000000000000000000CC\r
+S31560004E8000000000000000000000000000000000BC\r
+S31560004E9000000000000000000000000000000000AC\r
+S31560004EA0000000000000000000000000000000009C\r
+S31560004EB0000000000000000000000000000000008C\r
+S31560004EC0000000000000000000000000000000007C\r
+S31560004ED0000000000000000000000000000000006C\r
+S31560004EE0000000000000000000000000000000005C\r
+S31560004EF0000000000000000000000000000000004C\r
+S31560004F00000000000000000000000000000000003B\r
+S31560004F10000000000000000000000000000000002B\r
+S31560004F20000000000000000000000000000000001B\r
+S31560004F30000000000000000000000000000000000B\r
+S31560004F4000000000000000000000000000000000FB\r
+S31560004F5000000000000000000000000000000000EB\r
+S31560004F6000000000000000000000000000000000DB\r
+S31560004F7000000000000000000000000000000000CB\r
+S31560004F8000000000000000000000000000000000BB\r
+S31560004F9000000000000000000000000000000000AB\r
+S31560004FA0000000000000000000000000000000009B\r
+S31560004FB0000000000000000000000000000000008B\r
+S31560004FC0000000000000000000000000000000007B\r
+S31560004FD0000000000000000000000000000000006B\r
+S31560004FE0000000000000000000000000000000005B\r
+S31560004FF0000000000000000000000000000000004B\r
+S31560005000000000000000000000000000000000003A\r
+S31560005010000000000000000000000000000000002A\r
+S31560005020000000000000000000000000000000001A\r
+S31560005030000000000000000000000000000000000A\r
+S3156000504000000000000000000000000000000000FA\r
+S3156000505000000000000000000000000000000000EA\r
+S3156000506000000000000000000000000000000000DA\r
+S3156000507000000000000000000000000000000000CA\r
+S3156000508000000000000000000000000000000000BA\r
+S3156000509000000000000000000000000000000000AA\r
+S315600050A0000000000000000000000000000000009A\r
+S315600050B0000000000000000000000000000000008A\r
+S315600050C0000000000000000000000000000000007A\r
+S315600050D0000000000000000000000000000000006A\r
+S315600050E0000000000000000000000000000000005A\r
+S315600050F0000000000000000000000000000000004A\r
+S315600051000000000000000000000000000000000039\r
+S315600051100000000000000000000000000000000029\r
+S315600051200000000000000000000000000000000019\r
+S315600051300000000000000000000000000000000009\r
+S3156000514000000000000000000000000000000000F9\r
+S3156000515000000000000000000000000000000000E9\r
+S3156000516000000000000000000000000000000000D9\r
+S3156000517000000000000000000000000000000000C9\r
+S3156000518000000000000000000000000000000000B9\r
+S3156000519000000000000000000000000000000000A9\r
+S315600051A00000000000000000000000000000000099\r
+S315600051B00000000000000000000000000000000089\r
+S315600051C00000000000000000000000000000000079\r
+S315600051D00000000000000000000000000000000069\r
+S315600051E00000000000000000000000000000000059\r
+S315600051F00000000000000000000000000000000049\r
+S315600052000000000000000000000000000000000038\r
+S315600052100000000000000000000000000000000028\r
+S315600052200000000000000000000000000000000018\r
+S315600052300000000000000000000000000000000008\r
+S3156000524000000000000000000000000000000000F8\r
+S3156000525000000000000000000000000000000000E8\r
+S3156000526000000000000000000000000000000000D8\r
+S3156000527000000000000000000000000000000000C8\r
+S3156000528000000000000000000000000000000000B8\r
+S3156000529000000000000000000000000000000000A8\r
+S315600052A00000000000000000000000000000000098\r
+S315600052B00000000000000000000000000000000088\r
+S315600052C00000000000000000000000000000000078\r
+S315600052D00000000000000000000000000000000068\r
+S315600052E00000000000000000000000000000000058\r
+S315600052F00000000000000000000000000000000048\r
+S315600053000000000000000000000000000000000037\r
+S315600053100000000000000000000000000000000027\r
+S315600053200000000000000000000000000000000017\r
+S315600053300000000000000000000000000000000007\r
+S3156000534000000000000000000000000000000000F7\r
+S3156000535000000000000000000000000000000000E7\r
+S3156000536000000000000000000000000000000000D7\r
+S3156000537000000000000000000000000000000000C7\r
+S3156000538000000000000000000000000000000000B7\r
+S3156000539000000000000000000000000000000000A7\r
+S315600053A00000000000000000000000000000000097\r
+S315600053B00000000000000000000000000000000087\r
+S315600053C00000000000000000000000000000000077\r
+S315600053D00000000000000000000000000000000067\r
+S315600053E00000000000000000000000000000000057\r
+S315600053F00000000000000000000000000000000047\r
+S315600054000000000000000000000000000000000036\r
+S315600054100000000000000000000000000000000026\r
+S315600054200000000000000000000000000000000016\r
+S315600054300000000000000000000000000000000006\r
+S3156000544000000000000000000000000000000000F6\r
+S3156000545000000000000000000000000000000000E6\r
+S3156000546000000000000000000000000000000000D6\r
+S3156000547000000000000000000000000000000000C6\r
+S3156000548000000000000000000000000000000000B6\r
+S3156000549000000000000000000000000000000000A6\r
+S315600054A00000000000000000000000000000000096\r
+S315600054B00000000000000000000000000000000086\r
+S315600054C00000000000000000000000000000000076\r
+S315600054D00000000000000000000000000000000066\r
+S315600054E00000000000000000000000000000000056\r
+S315600054F00000000000000000000000000000000046\r
+S315600055000000000000000000000000000000000035\r
+S315600055100000000000000000000000000000000025\r
+S315600055200000000000000000000000000000000015\r
+S315600055300000000000000000000000000000000005\r
+S3156000554000000000000000000000000000000000F5\r
+S3156000555000000000000000000000000000000000E5\r
+S3156000556000000000000000000000000000000000D5\r
+S3156000557000000000000000000000000000000000C5\r
+S3156000558000000000000000000000000000000000B5\r
+S3156000559000000000000000000000000000000000A5\r
+S315600055A00000000000000000000000000000000095\r
+S315600055B00000000000000000000000000000000085\r
+S315600055C00000000000000000000000000000000075\r
+S315600055D00000000000000000000000000000000065\r
+S315600055E00000000000000000000000000000000055\r
+S315600055F00000000000000000000000000000000045\r
+S315600056000000000000000000000000000000000034\r
+S315600056100000000000000000000000000000000024\r
+S315600056200000000000000000000000000000000014\r
+S315600056300000000000000000000000000000000004\r
+S3156000564000000000000000000000000000000000F4\r
+S3156000565000000000000000000000000000000000E4\r
+S3156000566000000000000000000000000000000000D4\r
+S3156000567000000000000000000000000000000000C4\r
+S3156000568000000000000000000000000000000000B4\r
+S3156000569000000000000000000000000000000000A4\r
+S315600056A00000000000000000000000000000000094\r
+S315600056B00000000000000000000000000000000084\r
+S315600056C00000000000000000000000000000000074\r
+S315600056D00000000000000000000000000000000064\r
+S315600056E00000000000000000000000000000000054\r
+S315600056F00000000000000000000000000000000044\r
+S315600057000000000000000000000000000000000033\r
+S315600057100000000000000000000000000000000023\r
+S315600057200000000000000000000000000000000013\r
+S315600057300000000000000000000000000000000003\r
+S3156000574000000000000000000000000000000000F3\r
+S3156000575000000000000000000000000000000000E3\r
+S3156000576000000000000000000000000000000000D3\r
+S3156000577000000000000000000000000000000000C3\r
+S3156000578000000000000000000000000000000000B3\r
+S3156000579000000000000000000000000000000000A3\r
+S315600057A00000000000000000000000000000000093\r
+S315600057B00000000000000000000000000000000083\r
+S315600057C00000000000000000000000000000000073\r
+S315600057D00000000000000000000000000000000063\r
+S315600057E00000000000000000000000000000000053\r
+S315600057F00000000000000000000000000000000043\r
+S315600058000000000000000000000000000000000032\r
+S315600058100000000000000000000000000000000022\r
+S315600058200000000000000000000000000000000012\r
+S315600058300000000000000000000000000000000002\r
+S3156000584000000000000000000000000000000000F2\r
+S3156000585000000000000000000000000000000000E2\r
+S3156000586000000000000000000000000000000000D2\r
+S3156000587000000000000000000000000000000000C2\r
+S3156000588000000000000000000000000000000000B2\r
+S3156000589000000000000000000000000000000000A2\r
+S315600058A00000000000000000000000000000000092\r
+S315600058B00000000000000000000000000000000082\r
+S315600058C00000000000000000000000000000000072\r
+S315600058D00000000000000000000000000000000062\r
+S315600058E00000000000000000000000000000000052\r
+S315600058F00000000000000000000000000000000042\r
+S315600059000000000000000000000000000000000031\r
+S315600059100000000000000000000000000000000021\r
+S315600059200000000000000000000000000000000011\r
+S315600059300000000000000000000000000000000001\r
+S3156000594000000000000000000000000000000000F1\r
+S3156000595000000000000000000000000000000000E1\r
+S3156000596000000000000000000000000000000000D1\r
+S3156000597000000000000000000000000000000000C1\r
+S3156000598000000000000000000000000000000000B1\r
+S3156000599000000000000000000000000000000000A1\r
+S315600059A00000000000000000000000000000000091\r
+S315600059B00000000000000000000000000000000081\r
+S315600059C00000000000000000000000000000000071\r
+S315600059D00000000000000000000000000000000061\r
+S315600059E00000000000000000000000000000000051\r
+S315600059F00000000000000000000000000000000041\r
+S31560005A000000000000000000000000000000000030\r
+S31560005A100000000000000000000000000000000020\r
+S31560005A200000000000000000000000000000000010\r
+S31560005A300000000000000000000000000000000000\r
+S31560005A4000000000000000000000000000000000F0\r
+S31560005A5000000000000000000000000000000000E0\r
+S31560005A6000000000000000000000000000000000D0\r
+S31560005A7000000000000000000000000000000000C0\r
+S31560005A8000000000000000000000000000000000B0\r
+S31560005A9000000000000000000000000000000000A0\r
+S31560005AA00000000000000000000000000000000090\r
+S31560005AB00000000000000000000000000000000080\r
+S31560005AC00000000000000000000000000000000070\r
+S31560005AD00000000000000000000000000000000060\r
+S31560005AE00000000000000000000000000000000050\r
+S31560005AF00000000000000000000000000000000040\r
+S31560005B00000000000000000000000000000000002F\r
+S31560005B10000000000000000000000000000000001F\r
+S31560005B20000000000000000000000000000000000F\r
+S31560005B3000000000000000000000000000000000FF\r
+S31560005B4000000000000000000000000000000000EF\r
+S31560005B5000000000000000000000000000000000DF\r
+S31560005B6000000000000000000000000000000000CF\r
+S31560005B7000000000000000000000000000000000BF\r
+S31560005B8000000000000000000000000000000000AF\r
+S31560005B90000000000000000000000000000000009F\r
+S31560005BA0000000000000000000000000000000008F\r
+S31560005BB0000000000000000000000000000000007F\r
+S31560005BC0000000000000000000000000000000006F\r
+S31560005BD0000000000000000000000000000000005F\r
+S31560005BE0000000000000000000000000000000004F\r
+S31560005BF0000000000000000000000000000000003F\r
+S31560005C00000000000000000000000000000000002E\r
+S31560005C10000000000000000000000000000000001E\r
+S31560005C20000000000000000000000000000000000E\r
+S31560005C3000000000000000000000000000000000FE\r
+S31560005C4000000000000000000000000000000000EE\r
+S31560005C5000000000000000000000000000000000DE\r
+S31560005C6000000000000000000000000000000000CE\r
+S31560005C7000000000000000000000000000000000BE\r
+S31560005C8000000000000000000000000000000000AE\r
+S31560005C90000000000000000000000000000000009E\r
+S31560005CA0000000000000000000000000000000008E\r
+S31560005CB0000000000000000000000000000000007E\r
+S31560005CC0000000000000000000000000000000006E\r
+S31560005CD0000000000000000000000000000000005E\r
+S31560005CE0000000000000000000000000000000004E\r
+S31560005CF0000000000000000000000000000000003E\r
+S31560005D00000000000000000000000000000000002D\r
+S31560005D10000000000000000000000000000000001D\r
+S31560005D20000000000000000000000000000000000D\r
+S31560005D3000000000000000000000000000000000FD\r
+S31560005D4000000000000000000000000000000000ED\r
+S31560005D5000000000000000000000000000000000DD\r
+S31560005D6000000000000000000000000000000000CD\r
+S31560005D7000000000000000000000000000000000BD\r
+S31560005D8000000000000000000000000000000000AD\r
+S31560005D90000000000000000000000000000000009D\r
+S31560005DA0000000000000000000000000000000008D\r
+S31560005DB0000000000000000000000000000000007D\r
+S31560005DC0000000000000000000000000000000006D\r
+S31560005DD0000000000000000000000000000000005D\r
+S31560005DE0000000000000000000000000000000004D\r
+S31560005DF0000000000000000000000000000000003D\r
+S31560005E00000000000000000000000000000000002C\r
+S31560005E10000000000000000000000000000000001C\r
+S31560005E20000000000000000000000000000000000C\r
+S31560005E3000000000000000000000000000000000FC\r
+S31560005E4000000000000000000000000000000000EC\r
+S31560005E5000000000000000000000000000000000DC\r
+S31560005E6000000000000000000000000000000000CC\r
+S31560005E7000000000000000000000000000000000BC\r
+S31560005E8000000000000000000000000000000000AC\r
+S31560005E90000000000000000000000000000000009C\r
+S31560005EA0000000000000000000000000000000008C\r
+S31560005EB0000000000000000000000000000000007C\r
+S31560005EC0000000000000000000000000000000006C\r
+S31560005ED0000000000000000000000000000000005C\r
+S31560005EE0000000000000000000000000000000004C\r
+S31560005EF0000000000000000000000000000000003C\r
+S31560005F00000000000000000000000000000000002B\r
+S31560005F10000000000000000000000000000000001B\r
+S31560005F20000000000000000000000000000000000B\r
+S31560005F3000000000000000000000000000000000FB\r
+S31560005F4000000000000000000000000000000000EB\r
+S31560005F5000000000000000000000000000000000DB\r
+S31560005F6000000000000000000000000000000000CB\r
+S31560005F7000000000000000000000000000000000BB\r
+S31560005F8000000000000000000000000000000000AB\r
+S31560005F90000000000000000000000000000000009B\r
+S31560005FA0000000000000000000000000000000008B\r
+S31560005FB0000000000000000000000000000000007B\r
+S31560005FC0000000000000000000000000000000006B\r
+S31560005FD0000000000000000000000000000000005B\r
+S31560005FE0000000000000000000000000000000004B\r
+S31560005FF0000000000000000000000000000000003B\r
+S31560006000000000000000000000000000000000002A\r
+S31560006010000000000000000000000000000000001A\r
+S31560006020000000000000000000000000000000000A\r
+S3156000603000000000000000000000000000000000FA\r
+S3156000604000000000000000000000000000000000EA\r
+S3156000605000000000000000000000000000000000DA\r
+S3156000606000000000000000000000000000000000CA\r
+S3156000607000000000000000000000000000000000BA\r
+S3156000608000000000000000000000000000000000AA\r
+S31560006090000000000000000000000000000000009A\r
+S315600060A0000000000000000000000000000000008A\r
+S315600060B0000000000000000000000000000000007A\r
+S315600060C0000000000000000000000000000000006A\r
+S315600060D0000000000000000000000000000000005A\r
+S315600060E0000000000000000000000000000000004A\r
+S315600060F0000000000000000000000000000000003A\r
+S315600061000000000000000000000000000000000029\r
+S315600061100000000000000000000000000000000019\r
+S315600061200000000000000000000000000000000009\r
+S3156000613000000000000000000000000000000000F9\r
+S3156000614000000000000000000000000000000000E9\r
+S3156000615000000000000000000000000000000000D9\r
+S3156000616000000000000000000000000000000000C9\r
+S3156000617000000000000000000000000000000000B9\r
+S3156000618000000000000000000000000000000000A9\r
+S315600061900000000000000000000000000000000099\r
+S315600061A00000000000000000000000000000000089\r
+S315600061B00000000000000000000000000000000079\r
+S315600061C00000000000000000000000000000000069\r
+S315600061D00000000000000000000000000000000059\r
+S315600061E00000000000000000000000000000000049\r
+S315600061F00000000000000000000000000000000039\r
+S315600062000000000000000000000000000000000028\r
+S315600062100000000000000000000000000000000018\r
+S315600062200000000000000000000000000000000008\r
+S3156000623000000000000000000000000000000000F8\r
+S3156000624000000000000000000000000000000000E8\r
+S3156000625000000000000000000000000000000000D8\r
+S3156000626000000000000000000000000000000000C8\r
+S3156000627000000000000000000000000000000000B8\r
+S3156000628000000000000000000000000000000000A8\r
+S315600062900000000000000000000000000000000098\r
+S315600062A00000000000000000000000000000000088\r
+S315600062B00000000000000000000000000000000078\r
+S315600062C00000000000000000000000000000000068\r
+S315600062D00000000000000000000000000000000058\r
+S315600062E00000000000000000000000000000000048\r
+S315600062F00000000000000000000000000000000038\r
+S315600063000000000000000000000000000000000027\r
+S315600063100000000000000000000000000000000017\r
+S315600063200000000000000000000000000000000007\r
+S3156000633000000000000000000000000000000000F7\r
+S3156000634000000000000000000000000000000000E7\r
+S3156000635000000000000000000000000000000000D7\r
+S3156000636000000000000000000000000000000000C7\r
+S3156000637000000000000000000000000000000000B7\r
+S3156000638000000000000000000000000000000000A7\r
+S315600063900000000000000000000000000000000097\r
+S315600063A00000000000000000000000000000000087\r
+S315600063B00000000000000000000000000000000077\r
+S315600063C00000000000000000000000000000000067\r
+S315600063D00000000000000000000000000000000057\r
+S315600063E00000000000000000000000000000000047\r
+S315600063F00000000000000000000000000000000037\r
+S315600064000000000000000000000000000000000026\r
+S315600064100000000000000000000000000000000016\r
+S315600064200000000000000000000000000000000006\r
+S3156000643000000000000000000000000000000000F6\r
+S3156000644000000000000000000000000000000000E6\r
+S3156000645000000000000000000000000000000000D6\r
+S3156000646000000000000000000000000000000000C6\r
+S3156000647000000000000000000000000000000000B6\r
+S3156000648000000000000000000000000000000000A6\r
+S315600064900000000000000000000000000000000096\r
+S315600064A00000000000000000000000000000000086\r
+S315600064B00000000000000000000000000000000076\r
+S315600064C00000000000000000000000000000000066\r
+S315600064D00000000000000000000000000000000056\r
+S315600064E00000000000000000000000000000000046\r
+S315600064F00000000000000000000000000000000036\r
+S315600065000000000000000000000000000000000025\r
+S315600065100000000000000000000000000000000015\r
+S315600065200000000000000000000000000000000005\r
+S3156000653000000000000000000000000000000000F5\r
+S3156000654000000000000000000000000000000000E5\r
+S3156000655000000000000000000000000000000000D5\r
+S3156000656000000000000000000000000000000000C5\r
+S3156000657000000000000000000000000000000000B5\r
+S3156000658000000000000000000000000000000000A5\r
+S315600065900000000000000000000000000000000095\r
+S315600065A00000000000000000000000000000000085\r
+S315600065B00000000000000000000000000000000075\r
+S315600065C00000000000000000000000000000000065\r
+S315600065D00000000000000000000000000000000055\r
+S315600065E00000000000000000000000000000000045\r
+S315600065F00000000000000000000000000000000035\r
+S315600066000000000000000000000000000000000024\r
+S315600066100000000000000000000000000000000014\r
+S315600066200000000000000000000000000000000004\r
+S3156000663000000000000000000000000000000000F4\r
+S3156000664000000000000000000000000000000000E4\r
+S3156000665000000000000000000000000000000000D4\r
+S3156000666000000000000000000000000000000000C4\r
+S3156000667000000000000000000000000000000000B4\r
+S3156000668000000000000000000000000000000000A4\r
+S315600066900000000000000000000000000000000094\r
+S315600066A00000000000000000000000000000000084\r
+S315600066B00000000000000000000000000000000074\r
+S315600066C00000000000000000000000000000000064\r
+S315600066D00000000000000000000000000000000054\r
+S315600066E00000000000000000000000000000000044\r
+S315600066F00000000000000000000000000000000034\r
+S315600067000000000000000000000000000000000023\r
+S315600067100000000000000000000000000000000013\r
+S315600067200000000000000000000000000000000003\r
+S3156000673000000000000000000000000000000000F3\r
+S3156000674000000000000000000000000000000000E3\r
+S3156000675000000000000000000000000000000000D3\r
+S3156000676000000000000000000000000000000000C3\r
+S3156000677000000000000000000000000000000000B3\r
+S3156000678000000000000000000000000000000000A3\r
+S315600067900000000000000000000000000000000093\r
+S315600067A00000000000000000000000000000000083\r
+S315600067B00000000000000000000000000000000073\r
+S315600067C00000000000000000000000000000000063\r
+S315600067D00000000000000000000000000000000053\r
+S315600067E00000000000000000000000000000000043\r
+S315600067F00000000000000000000000000000000033\r
+S315600068000000000000000000000000000000000022\r
+S315600068100000000000000000000000000000000012\r
+S315600068200000000000000000000000000000000002\r
+S3156000683000000000000000000000000000000000F2\r
+S3156000684000000000000000000000000000000000E2\r
+S3156000685000000000000000000000000000000000D2\r
+S3156000686000000000000000000000000000000000C2\r
+S3156000687000000000000000000000000000000000B2\r
+S3156000688000000000000000000000000000000000A2\r
+S315600068900000000000000000000000000000000092\r
+S315600068A00000000000000000000000000000000082\r
+S315600068B00000000000000000000000000000000072\r
+S315600068C00000000000000000000000000000000062\r
+S315600068D00000000000000000000000000000000052\r
+S315600068E00000000000000000000000000000000042\r
+S315600068F00000000000000000000000000000000032\r
+S315600069000000000000000000000000000000000021\r
+S315600069100000000000000000000000000000000011\r
+S315600069200000000000000000000000000000000001\r
+S3156000693000000000000000000000000000000000F1\r
+S3156000694000000000000000000000000000000000E1\r
+S3156000695000000000000000000000000000000000D1\r
+S3156000696000000000000000000000000000000000C1\r
+S3156000697000000000000000000000000000000000B1\r
+S3156000698000000000000000000000000000000000A1\r
+S315600069900000000000000000000000000000000091\r
+S315600069A00000000000000000000000000000000081\r
+S315600069B00000000000000000000000000000000071\r
+S315600069C00000000000000000000000000000000061\r
+S315600069D00000000000000000000000000000000051\r
+S315600069E00000000000000000000000000000000041\r
+S315600069F00000000000000000000000000000000031\r
+S31560006A000000000000000000000000000000000020\r
+S31560006A100000000000000000000000000000000010\r
+S31560006A200000000000000000000000000000000000\r
+S31560006A3000000000000000000000000000000000F0\r
+S31560006A4000000000000000000000000000000000E0\r
+S31560006A5000000000000000000000000000000000D0\r
+S31560006A6000000000000000000000000000000000C0\r
+S31560006A7000000000000000000000000000000000B0\r
+S31560006A8000000000000000000000000000000000A0\r
+S31560006A900000000000000000000000000000000090\r
+S31560006AA00000000000000000000000000000000080\r
+S31560006AB00000000000000000000000000000000070\r
+S31560006AC00000000000000000000000000000000060\r
+S31560006AD00000000000000000000000000000000050\r
+S31560006AE00000000000000000000000000000000040\r
+S31560006AF00000000000000000000000000000000030\r
+S31560006B00000000000000000000000000000000001F\r
+S31560006B10000000000000000000000000000000000F\r
+S31560006B2000000000000000000000000000000000FF\r
+S31560006B3000000000000000000000000000000000EF\r
+S31560006B4000000000000000000000000000000000DF\r
+S31560006B5000000000000000000000000000000000CF\r
+S31560006B6000000000000000000000000000000000BF\r
+S31560006B7000000000000000000000000000000000AF\r
+S31560006B80000000000000000000000000000000009F\r
+S31560006B90000000000000000000000000000000008F\r
+S31560006BA0000000000000000000000000000000007F\r
+S31560006BB0000000000000000000000000000000006F\r
+S31560006BC0000000000000000000000000000000005F\r
+S31560006BD0000000000000000000000000000000004F\r
+S31560006BE0000000000000000000000000000000003F\r
+S31560006BF0000000000000000000000000000000002F\r
+S31560006C00000000000000000000000000000000001E\r
+S31560006C10000000000000000000000000000000000E\r
+S31560006C2000000000000000000000000000000000FE\r
+S31560006C3000000000000000000000000000000000EE\r
+S31560006C4000000000000000000000000000000000DE\r
+S31560006C5000000000000000000000000000000000CE\r
+S31560006C6000000000000000000000000000000000BE\r
+S31560006C7000000000000000000000000000000000AE\r
+S31560006C80000000000000000000000000000000009E\r
+S31560006C90000000000000000000000000000000008E\r
+S31560006CA0000000000000000000000000000000007E\r
+S31560006CB0000000000000000000000000000000006E\r
+S31560006CC0000000000000000000000000000000005E\r
+S31560006CD0000000000000000000000000000000004E\r
+S31560006CE0000000000000000000000000000000003E\r
+S31560006CF0000000000000000000000000000000002E\r
+S31560006D00000000000000000000000000000000001D\r
+S31560006D10000000000000000000000000000000000D\r
+S31560006D2000000000000000000000000000000000FD\r
+S31560006D3000000000000000000000000000000000ED\r
+S31560006D4000000000000000000000000000000000DD\r
+S31560006D5000000000000000000000000000000000CD\r
+S31560006D6000000000000000000000000000000000BD\r
+S31560006D7000000000000000000000000000000000AD\r
+S31560006D80000000000000000000000000000000009D\r
+S31560006D90000000000000000000000000000000008D\r
+S31560006DA0000000000000000000000000000000007D\r
+S31560006DB0000000000000000000000000000000006D\r
+S31560006DC0000000000000000000000000000000005D\r
+S31560006DD0000000000000000000000000000000004D\r
+S31560006DE0000000000000000000000000000000003D\r
+S31560006DF0000000000000000000000000000000002D\r
+S31560006E00000000000000000000000000000000001C\r
+S31560006E10000000000000000000000000000000000C\r
+S31560006E2000000000000000000000000000000000FC\r
+S31560006E3000000000000000000000000000000000EC\r
+S31560006E4000000000000000000000000000000000DC\r
+S31560006E5000000000000000000000000000000000CC\r
+S31560006E6000000000000000000000000000000000BC\r
+S31560006E7000000000000000000000000000000000AC\r
+S31560006E80000000000000000000000000000000009C\r
+S31560006E90000000000000000000000000000000008C\r
+S31560006EA0000000000000000000000000000000007C\r
+S31560006EB0000000000000000000000000000000006C\r
+S31560006EC0000000000000000000000000000000005C\r
+S31560006ED0000000000000000000000000000000004C\r
+S31560006EE0000000000000000000000000000000003C\r
+S31560006EF0000000000000000000000000000000002C\r
+S31560006F00000000000000000000000000000000001B\r
+S31560006F10000000000000000000000000000000000B\r
+S31560006F2000000000000000000000000000000000FB\r
+S31560006F3000000000000000000000000000000000EB\r
+S31560006F4000000000000000000000000000000000DB\r
+S31560006F5000000000000000000000000000000000CB\r
+S31560006F6000000000000000000000000000000000BB\r
+S31560006F7000000000000000000000000000000000AB\r
+S31560006F80000000000000000000000000000000009B\r
+S31560006F90000000000000000000000000000000008B\r
+S31560006FA0000000000000000000000000000000007B\r
+S31560006FB0000000000000000000000000000000006B\r
+S31560006FC0000000000000000000000000000000005B\r
+S31560006FD0000000000000000000000000000000004B\r
+S31560006FE0000000000000000000000000000000003B\r
+S31560006FF0000000000000000000000000000000002B\r
+S31560007000000000000000000000000000000000001A\r
+S31560007010000000000000000000000000000000000A\r
+S3156000702000000000000000000000000000000000FA\r
+S3156000703000000000000000000000000000000000EA\r
+S3156000704000000000000000000000000000000000DA\r
+S3156000705000000000000000000000000000000000CA\r
+S3156000706000000000000000000000000000000000BA\r
+S3156000707000000000000000000000000000000000AA\r
+S31560007080000000000000000000000000000000009A\r
+S31560007090000000000000000000000000000000008A\r
+S315600070A0000000000000000000000000000000007A\r
+S315600070B0000000000000000000000000000000006A\r
+S315600070C0000000000000000000000000000000005A\r
+S315600070D0000000000000000000000000000000004A\r
+S315600070E0000000000000000000000000000000003A\r
+S315600070F0000000000000000000000000000000002A\r
+S315600071000000000000000000000000000000000019\r
+S315600071100000000000000000000000000000000009\r
+S3156000712000000000000000000000000000000000F9\r
+S3156000713000000000000000000000000000000000E9\r
+S3156000714000000000000000000000000000000000D9\r
+S3156000715000000000000000000000000000000000C9\r
+S3156000716000000000000000000000000000000000B9\r
+S3156000717000000000000000000000000000000000A9\r
+S315600071800000000000000000000000000000000099\r
+S315600071900000000000000000000000000000000089\r
+S315600071A00000000000000000000000000000000079\r
+S315600071B00000000000000000000000000000000069\r
+S315600071C00000000000000000000000000000000059\r
+S315600071D00000000000000000000000000000000049\r
+S315600071E00000000000000000000000000000000039\r
+S315600071F00000000000000000000000000000000029\r
+S315600072000000000000000000000000000000000018\r
+S315600072100000000000000000000000000000000008\r
+S3156000722000000000000000000000000000000000F8\r
+S3156000723000000000000000000000000000000000E8\r
+S3156000724000000000000000000000000000000000D8\r
+S3156000725000000000000000000000000000000000C8\r
+S3156000726000000000000000000000000000000000B8\r
+S3156000727000000000000000000000000000000000A8\r
+S315600072800000000000000000000000000000000098\r
+S315600072900000000000000000000000000000000088\r
+S315600072A00000000000000000000000000000000078\r
+S315600072B00000000000000000000000000000000068\r
+S315600072C00000000000000000000000000000000058\r
+S315600072D00000000000000000000000000000000048\r
+S315600072E00000000000000000000000000000000038\r
+S315600072F00000000000000000000000000000000028\r
+S315600073000000000000000000000000000000000017\r
+S315600073100000000000000000000000000000000007\r
+S3156000732000000000000000000000000000000000F7\r
+S3156000733000000000000000000000000000000000E7\r
+S3156000734000000000000000000000000000000000D7\r
+S3156000735000000000000000000000000000000000C7\r
+S3156000736000000000000000000000000000000000B7\r
+S3156000737000000000000000000000000000000000A7\r
+S315600073800000000000000000000000000000000097\r
+S315600073900000000000000000000000000000000087\r
+S315600073A00000000000000000000000000000000077\r
+S315600073B00000000000000000000000000000000067\r
+S315600073C00000000000000000000000000000000057\r
+S315600073D00000000000000000000000000000000047\r
+S315600073E00000000000000000000000000000000037\r
+S315600073F00000000000000000000000000000000027\r
+S315600074000000000000000000000000000000000016\r
+S315600074100000000000000000000000000000000006\r
+S3156000742000000000000000000000000000000000F6\r
+S3156000743000000000000000000000000000000000E6\r
+S3156000744000000000000000000000000000000000D6\r
+S3156000745000000000000000000000000000000000C6\r
+S3156000746000000000000000000000000000000000B6\r
+S3156000747000000000000000000000000000000000A6\r
+S315600074800000000000000000000000000000000096\r
+S315600074900000000000000000000000000000000086\r
+S315600074A00000000000000000000000000000000076\r
+S315600074B00000000000000000000000000000000066\r
+S315600074C00000000000000000000000000000000056\r
+S315600074D00000000000000000000000000000000046\r
+S315600074E00000000000000000000000000000000036\r
+S315600074F00000000000000000000000000000000026\r
+S315600075000000000000000000000000000000000015\r
+S315600075100000000000000000000000000000000005\r
+S3156000752000000000000000000000000000000000F5\r
+S3156000753000000000000000000000000000000000E5\r
+S3156000754000000000000000000000000000000000D5\r
+S3156000755000000000000000000000000000000000C5\r
+S3156000756000000000000000000000000000000000B5\r
+S3156000757000000000000000000000000000000000A5\r
+S315600075800000000000000000000000000000000095\r
+S315600075900000000000000000000000000000000085\r
+S315600075A00000000000000000000000000000000075\r
+S315600075B00000000000000000000000000000000065\r
+S315600075C00000000000000000000000000000000055\r
+S315600075D00000000000000000000000000000000045\r
+S315600075E00000000000000000000000000000000035\r
+S315600075F00000000000000000000000000000000025\r
+S315600076000000000000000000000000000000000014\r
+S315600076100000000000000000000000000000000004\r
+S3156000762000000000000000000000000000000000F4\r
+S3156000763000000000000000000000000000000000E4\r
+S3156000764000000000000000000000000000000000D4\r
+S3156000765000000000000000000000000000000000C4\r
+S3156000766000000000000000000000000000000000B4\r
+S3156000767000000000000000000000000000000000A4\r
+S315600076800000000000000000000000000000000094\r
+S315600076900000000000000000000000000000000084\r
+S315600076A00000000000000000000000000000000074\r
+S315600076B00000000000000000000000000000000064\r
+S315600076C00000000000000000000000000000000054\r
+S315600076D00000000000000000000000000000000044\r
+S315600076E00000000000000000000000000000000034\r
+S315600076F00000000000000000000000000000000024\r
+S315600077000000000000000000000000000000000013\r
+S315600077100000000000000000000000000000000003\r
+S3156000772000000000000000000000000000000000F3\r
+S3156000773000000000000000000000000000000000E3\r
+S3156000774000000000000000000000000000000000D3\r
+S3156000775000000000000000000000000000000000C3\r
+S3156000776000000000000000000000000000000000B3\r
+S3156000777000000000000000000000000000000000A3\r
+S315600077800000000000000000000000000000000093\r
+S315600077900000000000000000000000000000000083\r
+S315600077A00000000000000000000000000000000073\r
+S315600077B00000000000000000000000000000000063\r
+S315600077C00000000000000000000000000000000053\r
+S315600077D00000000000000000000000000000000043\r
+S315600077E00000000000000000000000000000000033\r
+S315600077F00000000000000000000000000000000023\r
+S315600078000000000000000000000000000000000012\r
+S315600078100000000000000000000000000000000002\r
+S3156000782000000000000000000000000000000000F2\r
+S3156000783000000000000000000000000000000000E2\r
+S3156000784000000000000000000000000000000000D2\r
+S3156000785000000000000000000000000000000000C2\r
+S3156000786000000000000000000000000000000000B2\r
+S3156000787000000000000000000000000000000000A2\r
+S315600078800000000000000000000000000000000092\r
+S315600078900000000000000000000000000000000082\r
+S315600078A00000000000000000000000000000000072\r
+S315600078B00000000000000000000000000000000062\r
+S315600078C00000000000000000000000000000000052\r
+S315600078D00000000000000000000000000000000042\r
+S315600078E00000000000000000000000000000000032\r
+S315600078F00000000000000000000000000000000022\r
+S315600079000000000000000000000000000000000011\r
+S315600079100000000000000000000000000000000001\r
+S3156000792000000000000000000000000000000000F1\r
+S3156000793000000000000000000000000000000000E1\r
+S3156000794000000000000000000000000000000000D1\r
+S3156000795000000000000000000000000000000000C1\r
+S3156000796000000000000000000000000000000000B1\r
+S3156000797000000000000000000000000000000000A1\r
+S315600079800000000000000000000000000000000091\r
+S315600079900000000000000000000000000000000081\r
+S315600079A00000000000000000000000000000000071\r
+S315600079B00000000000000000000000000000000061\r
+S315600079C00000000000000000000000000000000051\r
+S315600079D00000000000000000000000000000000041\r
+S315600079E00000000000000000000000000000000031\r
+S315600079F00000000000000000000000000000000021\r
+S31560007A000000000000000000000000000000000010\r
+S31560007A100000000000000000000000000000000000\r
+S31560007A2000000000000000000000000000000000F0\r
+S31560007A3000000000000000000000000000000000E0\r
+S31560007A4000000000000000000000000000000000D0\r
+S31560007A5000000000000000000000000000000000C0\r
+S31560007A6000000000000000000000000000000000B0\r
+S31560007A7000000000000000000000000000000000A0\r
+S31560007A800000000000000000000000000000000090\r
+S31560007A900000000000000000000000000000000080\r
+S31560007AA00000000000000000000000000000000070\r
+S31560007AB00000000000000000000000000000000060\r
+S31560007AC00000000000000000000000000000000050\r
+S31560007AD00000000000000000000000000000000040\r
+S31560007AE00000000000000000000000000000000030\r
+S31560007AF00000000000000000000000000000000020\r
+S31560007B00000000000000000000000000000000000F\r
+S31560007B1000000000000000000000000000000000FF\r
+S31560007B2000000000000000000000000000000000EF\r
+S31560007B3000000000000000000000000000000000DF\r
+S31560007B4000000000000000000000000000000000CF\r
+S31560007B5000000000000000000000000000000000BF\r
+S31560007B6000000000000000000000000000000000AF\r
+S31560007B70000000000000000000000000000000009F\r
+S31560007B80000000000000000000000000000000008F\r
+S31560007B90000000000000000000000000000000007F\r
+S31560007BA0000000000000000000000000000000006F\r
+S31560007BB0000000000000000000000000000000005F\r
+S31560007BC0000000000000000000000000000000004F\r
+S31560007BD0000000000000000000000000000000003F\r
+S31560007BE0000000000000000000000000000000002F\r
+S31560007BF0000000000000000000000000000000001F\r
+S31560007C00000000000000000000000000000000000E\r
+S31560007C1000000000000000000000000000000000FE\r
+S31560007C2000000000000000000000000000000000EE\r
+S31560007C3000000000000000000000000000000000DE\r
+S31560007C4000000000000000000000000000000000CE\r
+S31560007C5000000000000000000000000000000000BE\r
+S31560007C6000000000000000000000000000000000AE\r
+S31560007C70000000000000000000000000000000009E\r
+S31560007C80000000000000000000000000000000008E\r
+S31560007C90000000000000000000000000000000007E\r
+S31560007CA0000000000000000000000000000000006E\r
+S31560007CB0000000000000000000000000000000005E\r
+S31560007CC0000000000000000000000000000000004E\r
+S31560007CD0000000000000000000000000000000003E\r
+S31560007CE0000000000000000000000000000000002E\r
+S31560007CF0000000000000000000000000000000001E\r
+S31560007D00000000000000000000000000000000000D\r
+S31560007D1000000000000000000000000000000000FD\r
+S31560007D2000000000000000000000000000000000ED\r
+S31560007D3000000000000000000000000000000000DD\r
+S31560007D4000000000000000000000000000000000CD\r
+S31560007D5000000000000000000000000000000000BD\r
+S31560007D6000000000000000000000000000000000AD\r
+S31560007D70000000000000000000000000000000009D\r
+S31560007D80000000000000000000000000000000008D\r
+S31560007D90000000000000000000000000000000007D\r
+S31560007DA0000000000000000000000000000000006D\r
+S31560007DB0000000000000000000000000000000005D\r
+S31560007DC0000000000000000000000000000000004D\r
+S31560007DD0000000000000000000000000000000003D\r
+S31560007DE0000000000000000000000000000000002D\r
+S31560007DF0000000000000000000000000000000001D\r
+S31560007E00000000000000000000000000000000000C\r
+S31560007E1000000000000000000000000000000000FC\r
+S31560007E2000000000000000000000000000000000EC\r
+S31560007E3000000000000000000000000000000000DC\r
+S31560007E4000000000000000000000000000000000CC\r
+S31560007E5000000000000000000000000000000000BC\r
+S31560007E6000000000000000000000000000000000AC\r
+S31560007E70000000000000000000000000000000009C\r
+S31560007E80000000000000000000000000000000008C\r
+S31560007E90000000000000000000000000000000007C\r
+S31560007EA0000000000000000000000000000000006C\r
+S31560007EB0000000000000000000000000000000005C\r
+S31560007EC0000000000000000000000000000000004C\r
+S31560007ED0000000000000000000000000000000003C\r
+S31560007EE0000000000000000000000000000000002C\r
+S31560007EF0000000000000000000000000000000001C\r
+S31560007F00000000000000000000000000000000000B\r
+S31560007F1000000000000000000000000000000000FB\r
+S31560007F2000000000000000000000000000000000EB\r
+S31560007F3000000000000000000000000000000000DB\r
+S31560007F4000000000000000000000000000000000CB\r
+S31560007F5000000000000000000000000000000000BB\r
+S31560007F6000000000000000000000000000000000AB\r
+S31560007F70000000000000000000000000000000009B\r
+S31560007F80000000000000000000000000000000008B\r
+S31560007F90000000000000000000000000000000007B\r
+S31560007FA0000000000000000000000000000000006B\r
+S31560007FB0000000000000000000000000000000005B\r
+S31560007FC0000000000000000000000000000000004B\r
+S31560007FD0000000000000000000000000000000003B\r
+S31560007FE0000000000000000000000000000000002B\r
+S31560007FF0000000000000000000000000000000001B\r
+S31560008000000000000000000000000000000000000A\r
+S3156000801000000000000000000000000000000000FA\r
+S3156000802000000000000000000000000000000000EA\r
+S3156000803000000000000000000000000000000000DA\r
+S3156000804000000000000000000000000000000000CA\r
+S3156000805000000000000000000000000000000000BA\r
+S3156000806000000000000000000000000000000000AA\r
+S31560008070000000000000000000000000000000009A\r
+S31560008080000000000000000000000000000000008A\r
+S31560008090000000000000000000000000000000007A\r
+S315600080A0000000000000000000000000000000006A\r
+S315600080B0000000000000000000000000000000005A\r
+S315600080C0000000000000000000000000000000004A\r
+S315600080D0000000000000000000000000000000003A\r
+S315600080E0000000000000000000000000000000002A\r
+S315600080F0000000000000000000000000000000001A\r
+S315600081000000000000000000000000000000000009\r
+S3156000811000000000000000000000000000000000F9\r
+S3156000812000000000000000000000000000000000E9\r
+S3156000813000000000000000000000000000000000D9\r
+S3156000814000000000000000000000000000000000C9\r
+S3156000815000000000000000000000000000000000B9\r
+S3156000816000000000000000000000000000000000A9\r
+S315600081700000000000000000000000000000000099\r
+S315600081800000000000000000000000000000000089\r
+S315600081900000000000000000000000000000000079\r
+S315600081A00000000000000000000000000000000069\r
+S315600081B00000000000000000000000000000000059\r
+S315600081C00000000000000000000000000000000049\r
+S315600081D00000000000000000000000000000000039\r
+S315600081E00000000000000000000000000000000029\r
+S315600081F00000000000000000000000000000000019\r
+S315600082000000000000000000000000000000000008\r
+S3156000821000000000000000000000000000000000F8\r
+S3156000822000000000000000000000000000000000E8\r
+S3156000823000000000000000000000000000000000D8\r
+S3156000824000000000000000000000000000000000C8\r
+S3156000825000000000000000000000000000000000B8\r
+S3156000826000000000000000000000000000000000A8\r
+S315600082700000000000000000000000000000000098\r
+S315600082800000000000000000000000000000000088\r
+S315600082900000000000000000000000000000000078\r
+S315600082A00000000000000000000000000000000068\r
+S315600082B00000000000000000000000000000000058\r
+S315600082C00000000000000000000000000000000048\r
+S315600082D00000000000000000000000000000000038\r
+S315600082E00000000000000000000000000000000028\r
+S315600082F00000000000000000000000000000000018\r
+S315600083000000000000000000000000000000000007\r
+S3156000831000000000000000000000000000000000F7\r
+S3156000832000000000000000000000000000000000E7\r
+S3156000833000000000000000000000000000000000D7\r
+S3156000834000000000000000000000000000000000C7\r
+S3156000835000000000000000000000000000000000B7\r
+S3156000836000000000000000000000000000000000A7\r
+S315600083700000000000000000000000000000000097\r
+S315600083800000000000000000000000000000000087\r
+S315600083900000000000000000000000000000000077\r
+S315600083A00000000000000000000000000000000067\r
+S315600083B00000000000000000000000000000000057\r
+S315600083C00000000000000000000000000000000047\r
+S315600083D00000000000000000000000000000000037\r
+S315600083E00000000000000000000000000000000027\r
+S315600083F00000000000000000000000000000000017\r
+S315600084000000000000000000000000000000000006\r
+S3156000841000000000000000000000000000000000F6\r
+S3156000842000000000000000000000000000000000E6\r
+S3156000843000000000000000000000000000000000D6\r
+S3156000844000000000000000000000000000000000C6\r
+S3156000845000000000000000000000000000000000B6\r
+S3156000846000000000000000000000000000000000A6\r
+S315600084700000000000000000000000000000000096\r
+S315600084800000000000000000000000000000000086\r
+S315600084900000000000000000000000000000000076\r
+S315600084A00000000000000000000000000000000066\r
+S315600084B00000000000000000000000000000000056\r
+S315600084C00000000000000000000000000000000046\r
+S315600084D00000000000000000000000000000000036\r
+S315600084E00000000000000000000000000000000026\r
+S315600084F00000000000000000000000000000000016\r
+S315600085000000000000000000000000000000000005\r
+S3156000851000000000000000000000000000000000F5\r
+S3156000852000000000000000000000000000000000E5\r
+S3156000853000000000000000000000000000000000D5\r
+S3156000854000000000000000000000000000000000C5\r
+S3156000855000000000000000000000000000000000B5\r
+S3156000856000000000000000000000000000000000A5\r
+S315600085700000000000000000000000000000000095\r
+S315600085800000000000000000000000000000000085\r
+S315600085900000000000000000000000000000000075\r
+S315600085A00000000000000000000000000000000065\r
+S315600085B00000000000000000000000000000000055\r
+S315600085C00000000000000000000000000000000045\r
+S315600085D00000000000000000000000000000000035\r
+S315600085E00000000000000000000000000000000025\r
+S315600085F00000000000000000000000000000000015\r
+S315600086000000000000000000000000000000000004\r
+S3156000861000000000000000000000000000000000F4\r
+S3156000862000000000000000000000000000000000E4\r
+S3156000863000000000000000000000000000000000D4\r
+S3156000864000000000000000000000000000000000C4\r
+S3156000865000000000000000000000000000000000B4\r
+S3156000866000000000000000000000000000000000A4\r
+S315600086700000000000000000000000000000000094\r
+S315600086800000000000000000000000000000000084\r
+S315600086900000000000000000000000000000000074\r
+S315600086A00000000000000000000000000000000064\r
+S315600086B00000000000000000000000000000000054\r
+S315600086C00000000000000000000000000000000044\r
+S315600086D00000000000000000000000000000000034\r
+S315600086E00000000000000000000000000000000024\r
+S315600086F00000000000000000000000000000000014\r
+S315600087000000000000000000000000000000000003\r
+S3156000871000000000000000000000000000000000F3\r
+S3156000872000000000000000000000000000000000E3\r
+S3156000873000000000000000000000000000000000D3\r
+S3156000874000000000000000000000000000000000C3\r
+S3156000875000000000000000000000000000000000B3\r
+S3156000876000000000000000000000000000000000A3\r
+S315600087700000000000000000000000000000000093\r
+S315600087800000000000000000000000000000000083\r
+S315600087900000000000000000000000000000000073\r
+S315600087A00000000000000000000000000000000063\r
+S315600087B00000000000000000000000000000000053\r
+S315600087C00000000000000000000000000000000043\r
+S315600087D00000000000000000000000000000000033\r
+S315600087E00000000000000000000000000000000023\r
+S315600087F00000000000000000000000000000000013\r
+S315600088000000000000000000000000000000000002\r
+S3156000881000000000000000000000000000000000F2\r
+S3156000882000000000000000000000000000000000E2\r
+S3156000883000000000000000000000000000000000D2\r
+S3156000884000000000000000000000000000000000C2\r
+S3156000885000000000000000000000000000000000B2\r
+S3156000886000000000000000000000000000000000A2\r
+S315600088700000000000000000000000000000000092\r
+S315600088800000000000000000000000000000000082\r
+S315600088900000000000000000000000000000000072\r
+S315600088A00000000000000000000000000000000062\r
+S315600088B00000000000000000000000000000000052\r
+S315600088C00000000000000000000000000000000042\r
+S315600088D00000000000000000000000000000000032\r
+S315600088E00000000000000000000000000000000022\r
+S315600088F00000000000000000000000000000000012\r
+S315600089000000000000000000000000000000000001\r
+S3156000891000000000000000000000000000000000F1\r
+S3156000892000000000000000000000000000000000E1\r
+S3156000893000000000000000000000000000000000D1\r
+S3156000894000000000000000000000000000000000C1\r
+S3156000895000000000000000000000000000000000B1\r
+S3156000896000000000000000000000000000000000A1\r
+S315600089700000000000000000000000000000000091\r
+S315600089800000000000000000000000000000000081\r
+S315600089900000000000000000000000000000000071\r
+S315600089A00000000000000000000000000000000061\r
+S315600089B00000000000000000000000000000000051\r
+S315600089C00000000000000000000000000000000041\r
+S315600089D00000000000000000000000000000000031\r
+S315600089E00000000000000000000000000000000021\r
+S315600089F00000000000000000000000000000000011\r
+S31560008A000000000000000000000000000000000000\r
+S31560008A1000000000000000000000000000000000F0\r
+S31560008A2000000000000000000000000000000000E0\r
+S31560008A3000000000000000000000000000000000D0\r
+S31560008A4000000000000000000000000000000000C0\r
+S31560008A5000000000000000000000000000000000B0\r
+S31560008A6000000000000000000000000000000000A0\r
+S31560008A700000000000000000000000000000000090\r
+S31560008A800000000000000000000000000000000080\r
+S31560008A900000000000000000000000000000000070\r
+S31560008AA00000000000000000000000000000000060\r
+S31560008AB00000000000000000000000000000000050\r
+S31560008AC00000000000000000000000000000000040\r
+S31560008AD00000000000000000000000000000000030\r
+S31560008AE00000000000000000000000000000000020\r
+S31560008AF00000000000000000000000000000000010\r
+S31560008B0000000000000000000000000000000000FF\r
+S31560008B1000000000000000000000000000000000EF\r
+S31560008B2000000000000000000000000000000000DF\r
+S31560008B3000000000000000000000000000000000CF\r
+S31560008B4000000000000000000000000000000000BF\r
+S31560008B5000000000000000000000000000000000AF\r
+S31560008B60000000000000000000000000000000009F\r
+S31560008B70000000000000000000000000000000008F\r
+S31560008B80000000000000000000000000000000007F\r
+S31560008B90000000000000000000000000000000006F\r
+S31560008BA0000000000000000000000000000000005F\r
+S31560008BB0000000000000000000000000000000004F\r
+S31560008BC0000000000000000000000000000000003F\r
+S31560008BD0000000000000000000000000000000002F\r
+S31560008BE0000000000000000000000000000000001F\r
+S31560008BF0000000000000000000000000000000000F\r
+S31560008C0000000000000000000000000000000000FE\r
+S31560008C1000000000000000000000000000000000EE\r
+S31560008C2000000000000000000000000000000000DE\r
+S31560008C3000000000000000000000000000000000CE\r
+S31560008C4000000000000000000000000000000000BE\r
+S31560008C5000000000000000000000000000000000AE\r
+S31560008C60000000000000000000000000000000009E\r
+S31560008C70000000000000000000000000000000008E\r
+S31560008C80000000000000000000000000000000007E\r
+S31560008C90000000000000000000000000000000006E\r
+S31560008CA0000000000000000000000000000000005E\r
+S31560008CB0000000000000000000000000000000004E\r
+S31560008CC0000000000000000000000000000000003E\r
+S31560008CD0000000000000000000000000000000002E\r
+S31560008CE0000000000000000000000000000000001E\r
+S31560008CF0000000000000000000000000000000000E\r
+S31560008D0000000000000000000000000000000000FD\r
+S31560008D1000000000000000000000000000000000ED\r
+S31560008D2000000000000000000000000000000000DD\r
+S31560008D3000000000000000000000000000000000CD\r
+S31560008D4000000000000000000000000000000000BD\r
+S31560008D5000000000000000000000000000000000AD\r
+S31560008D60000000000000000000000000000000009D\r
+S31560008D70000000000000000000000000000000008D\r
+S31560008D80000000000000000000000000000000007D\r
+S31560008D90000000000000000000000000000000006D\r
+S31560008DA0000000000000000000000000000000005D\r
+S31560008DB0000000000000000000000000000000004D\r
+S31560008DC0000000000000000000000000000000003D\r
+S31560008DD0000000000000000000000000000000002D\r
+S31560008DE0000000000000000000000000000000001D\r
+S31560008DF0000000000000000000000000000000000D\r
+S31560008E0000000000000000000000000000000000FC\r
+S31560008E1000000000000000000000000000000000EC\r
+S31560008E2000000000000000000000000000000000DC\r
+S31560008E3000000000000000000000000000000000CC\r
+S31560008E4000000000000000000000000000000000BC\r
+S31560008E5000000000000000000000000000000000AC\r
+S31560008E60000000000000000000000000000000009C\r
+S31560008E70000000000000000000000000000000008C\r
+S31560008E80000000000000000000000000000000007C\r
+S31560008E90000000000000000000000000000000006C\r
+S31560008EA0000000000000000000000000000000005C\r
+S31560008EB0000000000000000000000000000000004C\r
+S31560008EC0000000000000000000000000000000003C\r
+S31560008ED0000000000000000000000000000000002C\r
+S31560008EE0000000000000000000000000000000001C\r
+S31560008EF0000000000000000000000000000000000C\r
+S31560008F0000000000000000000000000000000000FB\r
+S31560008F1000000000000000000000000000000000EB\r
+S31560008F2000000000000000000000000000000000DB\r
+S31560008F3000000000000000000000000000000000CB\r
+S31560008F4000000000000000000000000000000000BB\r
+S31560008F5000000000000000000000000000000000AB\r
+S31560008F60000000000000000000000000000000009B\r
+S31560008F70000000000000000000000000000000008B\r
+S31560008F80000000000000000000000000000000007B\r
+S31560008F90000000000000000000000000000000006B\r
+S31560008FA0000000000000000000000000000000005B\r
+S31560008FB0000000000000000000000000000000004B\r
+S31560008FC0000000000000000000000000000000003B\r
+S31560008FD0000000000000000000000000000000002B\r
+S31560008FE0000000000000000000000000000000001B\r
+S31560008FF0000000000000000000000000000000000B\r
+S3156000900000000000000000000000000000000000FA\r
+S3156000901000000000000000000000000000000000EA\r
+S3156000902000000000000000000000000000000000DA\r
+S3156000903000000000000000000000000000000000CA\r
+S3156000904000000000000000000000000000000000BA\r
+S3156000905000000000000000000000000000000000AA\r
+S31560009060000000000000000000000000000000009A\r
+S31560009070000000000000000000000000000000008A\r
+S31560009080000000000000000000000000000000007A\r
+S31560009090000000000000000000000000000000006A\r
+S315600090A0000000000000000000000000000000005A\r
+S315600090B0000000000000000000000000000000004A\r
+S315600090C0000000000000000000000000000000003A\r
+S315600090D0000000000000000000000000000000002A\r
+S315600090E0000000000000000000000000000000001A\r
+S315600090F0000000000000000000000000000000000A\r
+S3156000910000000000000000000000000000000000F9\r
+S3156000911000000000000000000000000000000000E9\r
+S3156000912000000000000000000000000000000000D9\r
+S3156000913000000000000000000000000000000000C9\r
+S3156000914000000000000000000000000000000000B9\r
+S3156000915000000000000000000000000000000000A9\r
+S315600091600000000000000000000000000000000099\r
+S315600091700000000000000000000000000000000089\r
+S315600091800000000000000000000000000000000079\r
+S315600091900000000000000000000000000000000069\r
+S315600091A00000000000000000000000000000000059\r
+S315600091B00000000000000000000000000000000049\r
+S315600091C00000000000000000000000000000000039\r
+S315600091D00000000000000000000000000000000029\r
+S315600091E00000000000000000000000000000000019\r
+S315600091F00000000000000000000000000000000009\r
+S3156000920000000000000000000000000000000000F8\r
+S3156000921000000000000000000000000000000000E8\r
+S3156000922000000000000000000000000000000000D8\r
+S3156000923000000000000000000000000000000000C8\r
+S3156000924000000000000000000000000000000000B8\r
+S3156000925000000000000000000000000000000000A8\r
+S315600092600000000000000000000000000000000098\r
+S315600092700000000000000000000000000000000088\r
+S315600092800000000000000000000000000000000078\r
+S315600092900000000000000000000000000000000068\r
+S315600092A00000000000000000000000000000000058\r
+S315600092B00000000000000000000000000000000048\r
+S315600092C00000000000000000000000000000000038\r
+S315600092D00000000000000000000000000000000028\r
+S315600092E00000000000000000000000000000000018\r
+S315600092F00000000000000000000000000000000008\r
+S3156000930000000000000000000000000000000000F7\r
+S3156000931000000000000000000000000000000000E7\r
+S3156000932000000000000000000000000000000000D7\r
+S3156000933000000000000000000000000000000000C7\r
+S3156000934000000000000000000000000000000000B7\r
+S3156000935000000000000000000000000000000000A7\r
+S315600093600000000000000000000000000000000097\r
+S315600093700000000000000000000000000000000087\r
+S315600093800000000000000000000000000000000077\r
+S315600093900000000000000000000000000000000067\r
+S315600093A00000000000000000000000000000000057\r
+S315600093B00000000000000000000000000000000047\r
+S315600093C00000000000000000000000000000000037\r
+S315600093D00000000000000000000000000000000027\r
+S315600093E00000000000000000000000000000000017\r
+S315600093F00000000000000000000000000000000007\r
+S3156000940000000000000000000000000000000000F6\r
+S3156000941000000000000000000000000000000000E6\r
+S3156000942000000000000000000000000000000000D6\r
+S3156000943000000000000000000000000000000000C6\r
+S3156000944000000000000000000000000000000000B6\r
+S3156000945000000000000000000000000000000000A6\r
+S315600094600000000000000000000000000000000096\r
+S315600094700000000000000000000000000000000086\r
+S315600094800000000000000000000000000000000076\r
+S315600094900000000000000000000000000000000066\r
+S315600094A00000000000000000000000000000000056\r
+S315600094B00000000000000000000000000000000046\r
+S315600094C00000000000000000000000000000000036\r
+S315600094D00000000000000000000000000000000026\r
+S315600094E00000000000000000000000000000000016\r
+S315600094F00000000000000000000000000000000006\r
+S3156000950000000000000000000000000000000000F5\r
+S3156000951000000000000000000000000000000000E5\r
+S3156000952000000000000000000000000000000000D5\r
+S3156000953000000000000000000000000000000000C5\r
+S3156000954000000000000000000000000000000000B5\r
+S3156000955000000000000000000000000000000000A5\r
+S315600095600000000000000000000000000000000095\r
+S315600095700000000000000000000000000000000085\r
+S315600095800000000000000000000000000000000075\r
+S315600095900000000000000000000000000000000065\r
+S315600095A00000000000000000000000000000000055\r
+S315600095B00000000000000000000000000000000045\r
+S315600095C00000000000000000000000000000000035\r
+S315600095D00000000000000000000000000000000025\r
+S315600095E00000000000000000000000000000000015\r
+S315600095F00000000000000000000000000000000005\r
+S3156000960000000000000000000000000000000000F4\r
+S3156000961000000000000000000000000000000000E4\r
+S3156000962000000000000000000000000000000000D4\r
+S3156000963000000000000000000000000000000000C4\r
+S3156000964000000000000000000000000000000000B4\r
+S3156000965000000000000000000000000000000000A4\r
+S315600096600000000000000000000000000000000094\r
+S315600096700000000000000000000000000000000084\r
+S315600096800000000000000000000000000000000074\r
+S315600096900000000000000000000000000000000064\r
+S315600096A00000000000000000000000000000000054\r
+S315600096B00000000000000000000000000000000044\r
+S315600096C00000000000000000000000000000000034\r
+S315600096D00000000000000000000000000000000024\r
+S315600096E00000000000000000000000000000000014\r
+S315600096F00000000000000000000000000000000004\r
+S3156000970000000000000000000000000000000000F3\r
+S3156000971000000000000000000000000000000000E3\r
+S3156000972000000000000000000000000000000000D3\r
+S3156000973000000000000000000000000000000000C3\r
+S3156000974000000000000000000000000000000000B3\r
+S3156000975000000000000000000000000000000000A3\r
+S315600097600000000000000000000000000000000093\r
+S315600097700000000000000000000000000000000083\r
+S315600097800000000000000000000000000000000073\r
+S315600097900000000000000000000000000000000063\r
+S315600097A00000000000000000000000000000000053\r
+S315600097B00000000000000000000000000000000043\r
+S315600097C00000000000000000000000000000000033\r
+S315600097D00000000000000000000000000000000023\r
+S315600097E00000000000000000000000000000000013\r
+S315600097F00000000000000000000000000000000003\r
+S3156000980000000000000000000000000000000000F2\r
+S3156000981000000000000000000000000000000000E2\r
+S3156000982000000000000000000000000000000000D2\r
+S3156000983000000000000000000000000000000000C2\r
+S3156000984000000000000000000000000000000000B2\r
+S3156000985000000000000000000000000000000000A2\r
+S315600098600000000000000000000000000000000092\r
+S315600098700000000000000000000000000000000082\r
+S315600098800000000000000000000000000000000072\r
+S315600098900000000000000000000000000000000062\r
+S315600098A00000000000000000000000000000000052\r
+S315600098B00000000000000000000000000000000042\r
+S315600098C00000000000000000000000000000000032\r
+S315600098D00000000000000000000000000000000022\r
+S315600098E00000000000000000000000000000000012\r
+S315600098F00000000000000000000000000000000002\r
+S3156000990000000000000000000000000000000000F1\r
+S3156000991000000000000000000000000000000000E1\r
+S3156000992000000000000000000000000000000000D1\r
+S3156000993000000000000000000000000000000000C1\r
+S3156000994000000000000000000000000000000000B1\r
+S3156000995000000000000000000000000000000000A1\r
+S315600099600000000000000000000000000000000091\r
+S315600099700000000000000000000000000000000081\r
+S315600099800000000000000000000000000000000071\r
+S315600099900000000000000000000000000000000061\r
+S315600099A00000000000000000000000000000000051\r
+S315600099B00000000000000000000000000000000041\r
+S315600099C00000000000000000000000000000000031\r
+S315600099D00000000000000000000000000000000021\r
+S315600099E00000000000000000000000000000000011\r
+S315600099F00000000000000000000000000000000001\r
+S31560009A0000000000000000000000000000000000F0\r
+S31560009A1000000000000000000000000000000000E0\r
+S31560009A2000000000000000000000000000000000D0\r
+S31560009A3000000000000000000000000000000000C0\r
+S31560009A4000000000000000000000000000000000B0\r
+S31560009A5000000000000000000000000000000000A0\r
+S31560009A600000000000000000000000000000000090\r
+S31560009A700000000000000000000000000000000080\r
+S31560009A800000000000000000000000000000000070\r
+S31560009A900000000000000000000000000000000060\r
+S31560009AA00000000000000000000000000000000050\r
+S31560009AB00000000000000000000000000000000040\r
+S31560009AC00000000000000000000000000000000030\r
+S31560009AD00000000000000000000000000000000020\r
+S31560009AE00000000000000000000000000000000010\r
+S31560009AF00000000000000000000000000000000000\r
+S31560009B0000000000000000000000000000000000EF\r
+S31560009B1000000000000000000000000000000000DF\r
+S31560009B2000000000000000000000000000000000CF\r
+S31560009B3000000000000000000000000000000000BF\r
+S31560009B4000000000000000000000000000000000AF\r
+S31560009B50000000000000000000000000000000009F\r
+S31560009B60000000000000000000000000000000008F\r
+S31560009B70000000000000000000000000000000007F\r
+S31560009B80000000000000000000000000000000006F\r
+S31560009B90000000000000000000000000000000005F\r
+S31560009BA0000000000000000000000000000000004F\r
+S31560009BB0000000000000000000000000000000003F\r
+S31560009BC0000000000000000000000000000000002F\r
+S31560009BD0000000000000000000000000000000001F\r
+S31560009BE0000000000000000000000000000000000F\r
+S31560009BF000000000000000000000000000000000FF\r
+S31560009C0000000000000000000000000000000000EE\r
+S31560009C1000000000000000000000000000000000DE\r
+S31560009C2000000000000000000000000000000000CE\r
+S31560009C3000000000000000000000000000000000BE\r
+S31560009C4000000000000000000000000000000000AE\r
+S31560009C50000000000000000000000000000000009E\r
+S31560009C60000000000000000000000000000000008E\r
+S31560009C70000000000000000000000000000000007E\r
+S31560009C80000000000000000000000000000000006E\r
+S31560009C90000000000000000000000000000000005E\r
+S31560009CA0000000000000000000000000000000004E\r
+S31560009CB0000000000000000000000000000000003E\r
+S31560009CC0000000000000000000000000000000002E\r
+S31560009CD0000000000000000000000000000000001E\r
+S31560009CE0000000000000000000000000000000000E\r
+S31560009CF000000000000000000000000000000000FE\r
+S31560009D0000000000000000000000000000000000ED\r
+S31560009D1000000000000000000000000000000000DD\r
+S31560009D2000000000000000000000000000000000CD\r
+S31560009D3000000000000000000000000000000000BD\r
+S31560009D4000000000000000000000000000000000AD\r
+S31560009D50000000000000000000000000000000009D\r
+S31560009D60000000000000000000000000000000008D\r
+S31560009D70000000000000000000000000000000007D\r
+S31560009D80000000000000000000000000000000006D\r
+S31560009D90000000000000000000000000000000005D\r
+S31560009DA0000000000000000000000000000000004D\r
+S31560009DB0000000000000000000000000000000003D\r
+S31560009DC0000000000000000000000000000000002D\r
+S31560009DD0000000000000000000000000000000001D\r
+S31560009DE0000000000000000000000000000000000D\r
+S31560009DF000000000000000000000000000000000FD\r
+S31560009E0000000000000000000000000000000000EC\r
+S31560009E1000000000000000000000000000000000DC\r
+S31560009E2000000000000000000000000000000000CC\r
+S31560009E3000000000000000000000000000000000BC\r
+S31560009E4000000000000000000000000000000000AC\r
+S31560009E50000000000000000000000000000000009C\r
+S31560009E60000000000000000000000000000000008C\r
+S31560009E70000000000000000000000000000000007C\r
+S31560009E80000000000000000000000000000000006C\r
+S31560009E90000000000000000000000000000000005C\r
+S31560009EA0000000000000000000000000000000004C\r
+S31560009EB0000000000000000000000000000000003C\r
+S31560009EC0000000000000000000000000000000002C\r
+S31560009ED0000000000000000000000000000000001C\r
+S31560009EE0000000000000000000000000000000000C\r
+S31560009EF000000000000000000000000000000000FC\r
+S31560009F0000000000000000000000000000000000EB\r
+S31560009F1000000000000000000000000000000000DB\r
+S31560009F2000000000000000000000000000000000CB\r
+S31560009F3000000000000000000000000000000000BB\r
+S31560009F4000000000000000000000000000000000AB\r
+S31560009F50000000000000000000000000000000009B\r
+S31560009F60000000000000000000000000000000008B\r
+S31560009F70000000000000000000000000000000007B\r
+S31560009F80000000000000000000000000000000006B\r
+S31560009F90000000000000000000000000000000005B\r
+S31560009FA0000000000000000000000000000000004B\r
+S31560009FB0000000000000000000000000000000003B\r
+S31560009FC0000000000000000000000000000000002B\r
+S31560009FD0000000000000000000000000000000001B\r
+S31560009FE0000000000000000000000000000000000B\r
+S31560009FF000000000000000000000000000000000FB\r
+S3156000A00000000000000000000000000000000000EA\r
+S3156000A01000000000000000000000000000000000DA\r
+S3156000A02000000000000000000000000000000000CA\r
+S3156000A03000000000000000000000000000000000BA\r
+S3156000A04000000000000000000000000000000000AA\r
+S3156000A050000000000000000000000000000000009A\r
+S3156000A060000000000000000000000000000000008A\r
+S3156000A070000000000000000000000000000000007A\r
+S3156000A080000000000000000000000000000000006A\r
+S3156000A090000000000000000000000000000000005A\r
+S3156000A0A0000000000000000000000000000000004A\r
+S3156000A0B0000000000000000000000000000000003A\r
+S3156000A0C0000000000000000000000000000000002A\r
+S3156000A0D0000000000000000000000000000000001A\r
+S3156000A0E0000000000000000000000000000000000A\r
+S3156000A0F000000000000000000000000000000000FA\r
+S3156000A10000000000000000000000000000000000E9\r
+S3156000A11000000000000000000000000000000000D9\r
+S3156000A12000000000000000000000000000000000C9\r
+S3156000A13000000000000000000000000000000000B9\r
+S3156000A14000000000000000000000000000000000A9\r
+S3156000A1500000000000000000000000000000000099\r
+S3156000A1600000000000000000000000000000000089\r
+S3156000A1700000000000000000000000000000000079\r
+S3156000A1800000000000000000000000000000000069\r
+S3156000A1900000000000000000000000000000000059\r
+S3156000A1A00000000000000000000000000000000049\r
+S3156000A1B00000000000000000000000000000000039\r
+S3156000A1C00000000000000000000000000000000029\r
+S3156000A1D00000000000000000000000000000000019\r
+S3156000A1E00000000000000000000000000000000009\r
+S3156000A1F000000000000000000000000000000000F9\r
+S3156000A20000000000000000000000000000000000E8\r
+S3156000A21000000000000000000000000000000000D8\r
+S3156000A22000000000000000000000000000000000C8\r
+S3156000A23000000000000000000000000000000000B8\r
+S3156000A24000000000000000000000000000000000A8\r
+S3156000A2500000000000000000000000000000000098\r
+S3156000A2600000000000000000000000000000000088\r
+S3156000A2700000000000000000000000000000000078\r
+S3156000A2800000000000000000000000000000000068\r
+S3156000A2900000000000000000000000000000000058\r
+S3156000A2A00000000000000000000000000000000048\r
+S3156000A2B00000000000000000000000000000000038\r
+S3156000A2C00000000000000000000000000000000028\r
+S3156000A2D00000000000000000000000000000000018\r
+S3156000A2E00000000000000000000000000000000008\r
+S3156000A2F000000000000000000000000000000000F8\r
+S3156000A30000000000000000000000000000000000E7\r
+S3156000A31000000000000000000000000000000000D7\r
+S3156000A32000000000000000000000000000000000C7\r
+S3156000A33000000000000000000000000000000000B7\r
+S3156000A34000000000000000000000000000000000A7\r
+S3156000A3500000000000000000000000000000000097\r
+S3156000A3600000000000000000000000000000000087\r
+S3156000A3700000000000000000000000000000000077\r
+S3156000A3800000000000000000000000000000000067\r
+S3156000A3900000000000000000000000000000000057\r
+S3156000A3A00000000000000000000000000000000047\r
+S3156000A3B00000000000000000000000000000000037\r
+S3156000A3C00000000000000000000000000000000027\r
+S3156000A3D00000000000000000000000000000000017\r
+S3156000A3E00000000000000000000000000000000007\r
+S3156000A3F000000000000000000000000000000000F7\r
+S3156000A40000000000000000000000000000000000E6\r
+S3156000A41000000000000000000000000000000000D6\r
+S3156000A42000000000000000000000000000000000C6\r
+S3156000A43000000000000000000000000000000000B6\r
+S3156000A44000000000000000000000000000000000A6\r
+S3156000A4500000000000000000000000000000000096\r
+S3156000A4600000000000000000000000000000000086\r
+S3156000A4700000000000000000000000000000000076\r
+S3156000A4800000000000000000000000000000000066\r
+S3156000A4900000000000000000000000000000000056\r
+S3156000A4A00000000000000000000000000000000046\r
+S3156000A4B00000000000000000000000000000000036\r
+S3156000A4C00000000000000000000000000000000026\r
+S3156000A4D00000000000000000000000000000000016\r
+S3156000A4E00000000000000000000000000000000006\r
+S3156000A4F000000000000000000000000000000000F6\r
+S3156000A50000000000000000000000000000000000E5\r
+S3156000A51000000000000000000000000000000000D5\r
+S3156000A52000000000000000000000000000000000C5\r
+S3156000A53000000000000000000000000000000000B5\r
+S3156000A54000000000000000000000000000000000A5\r
+S3156000A5500000000000000000000000000000000095\r
+S3156000A5600000000000000000000000000000000085\r
+S3156000A5700000000000000000000000000000000075\r
+S3156000A5800000000000000000000000000000000065\r
+S3156000A5900000000000000000000000000000000055\r
+S3156000A5A00000000000000000000000000000000045\r
+S3156000A5B00000000000000000000000000000000035\r
+S3156000A5C00000000000000000000000000000000025\r
+S3156000A5D00000000000000000000000000000000015\r
+S3156000A5E00000000000000000000000000000000005\r
+S3156000A5F000000000000000000000000000000000F5\r
+S3156000A60000000000000000000000000000000000E4\r
+S3156000A61000000000000000000000000000000000D4\r
+S3156000A62000000000000000000000000000000000C4\r
+S3156000A63000000000000000000000000000000000B4\r
+S3156000A64000000000000000000000000000000000A4\r
+S3156000A6500000000000000000000000000000000094\r
+S3156000A6600000000000000000000000000000000084\r
+S3156000A6700000000000000000000000000000000074\r
+S3156000A6800000000000000000000000000000000064\r
+S3156000A6900000000000000000000000000000000054\r
+S3156000A6A00000000000000000000000000000000044\r
+S3156000A6B00000000000000000000000000000000034\r
+S3156000A6C00000000000000000000000000000000024\r
+S3156000A6D00000000000000000000000000000000014\r
+S3156000A6E00000000000000000000000000000000004\r
+S3156000A6F000000000000000000000000000000000F4\r
+S3156000A70000000000000000000000000000000000E3\r
+S3156000A71000000000000000000000000000000000D3\r
+S3156000A72000000000000000000000000000000000C3\r
+S3156000A73000000000000000000000000000000000B3\r
+S3156000A74000000000000000000000000000000000A3\r
+S3156000A7500000000000000000000000000000000093\r
+S3156000A7600000000000000000000000000000000083\r
+S3156000A7700000000000000000000000000000000073\r
+S3156000A7800000000000000000000000000000000063\r
+S3156000A7900000000000000000000000000000000053\r
+S3156000A7A00000000000000000000000000000000043\r
+S3156000A7B00000000000000000000000000000000033\r
+S3156000A7C00000000000000000000000000000000023\r
+S3156000A7D00000000000000000000000000000000013\r
+S3156000A7E00000000000000000000000000000000003\r
+S3156000A7F000000000000000000000000000000000F3\r
+S3156000A80000000000000000000000000000000000E2\r
+S3156000A81000000000000000000000000000000000D2\r
+S3156000A82000000000000000000000000000000000C2\r
+S3156000A83000000000000000000000000000000000B2\r
+S3156000A84000000000000000000000000000000000A2\r
+S3156000A8500000000000000000000000000000000092\r
+S3156000A8600000000000000000000000000000000082\r
+S3156000A8700000000000000000000000000000000072\r
+S3156000A8800000000000000000000000000000000062\r
+S3156000A8900000000000000000000000000000000052\r
+S3156000A8A00000000000000000000000000000000042\r
+S3156000A8B00000000000000000000000000000000032\r
+S3156000A8C00000000000000000000000000000000022\r
+S3156000A8D00000000000000000000000000000000012\r
+S3156000A8E00000000000000000000000000000000002\r
+S3156000A8F000000000000000000000000000000000F2\r
+S3156000A90000000000000000000000000000000000E1\r
+S3156000A91000000000000000000000000000000000D1\r
+S3156000A92000000000000000000000000000000000C1\r
+S3156000A93000000000000000000000000000000000B1\r
+S3156000A94000000000000000000000000000000000A1\r
+S3156000A9500000000000000000000000000000000091\r
+S3156000A9600000000000000000000000000000000081\r
+S3156000A9700000000000000000000000000000000071\r
+S3156000A9800000000000000000000000000000000061\r
+S3156000A9900000000000000000000000000000000051\r
+S3156000A9A00000000000000000000000000000000041\r
+S3156000A9B00000000000000000000000000000000031\r
+S3156000A9C00000000000000000000000000000000021\r
+S3156000A9D00000000000000000000000000000000011\r
+S3156000A9E00000000000000000000000000000000001\r
+S3156000A9F000000000000000000000000000000000F1\r
+S3156000AA0000000000000000000000000000000000E0\r
+S3156000AA1000000000000000000000000000000000D0\r
+S3156000AA2000000000000000000000000000000000C0\r
+S3156000AA3000000000000000000000000000000000B0\r
+S3156000AA4000000000000000000000000000000000A0\r
+S3156000AA500000000000000000000000000000000090\r
+S3156000AA600000000000000000000000000000000080\r
+S3156000AA700000000000000000000000000000000070\r
+S3156000AA800000000000000000000000000000000060\r
+S3156000AA900000000000000000000000000000000050\r
+S3156000AAA00000000000000000000000000000000040\r
+S3156000AAB00000000000000000000000000000000030\r
+S3156000AAC00000000000000000000000000000000020\r
+S3156000AAD00000000000000000000000000000000010\r
+S3156000AAE00000000000000000000000000000000000\r
+S3156000AAF000000000000000000000000000000000F0\r
+S3156000AB0000000000000000000000000000000000DF\r
+S3156000AB1000000000000000000000000000000000CF\r
+S3156000AB2000000000000000000000000000000000BF\r
+S3156000AB3000000000000000000000000000000000AF\r
+S3156000AB40000000000000000000000000000000009F\r
+S3156000AB50000000000000000000000000000000008F\r
+S3156000AB60000000000000000000000000000000007F\r
+S3156000AB70000000000000000000000000000000006F\r
+S3156000AB80000000000000000000000000000000005F\r
+S3156000AB90000000000000000000000000000000004F\r
+S3156000ABA0000000000000000000000000000000003F\r
+S3156000ABB0000000000000000000000000000000002F\r
+S3156000ABC0000000000000000000000000000000001F\r
+S3156000ABD0000000000000000000000000000000000F\r
+S3156000ABE000000000000000000000000000000000FF\r
+S3156000ABF000000000000000000000000000000000EF\r
+S3156000AC0000000000000000000000000000000000DE\r
+S3156000AC1000000000000000000000000000000000CE\r
+S3156000AC2000000000000000000000000000000000BE\r
+S3156000AC3000000000000000000000000000000000AE\r
+S3156000AC40000000000000000000000000000000009E\r
+S3156000AC50000000000000000000000000000000008E\r
+S3156000AC60000000000000000000000000000000007E\r
+S3156000AC70000000000000000000000000000000006E\r
+S3156000AC80000000000000000000000000000000005E\r
+S3156000AC90000000000000000000000000000000004E\r
+S3156000ACA0000000000000000000000000000000003E\r
+S3156000ACB0000000000000000000000000000000002E\r
+S3156000ACC0000000000000000000000000000000001E\r
+S3156000ACD0000000000000000000000000000000000E\r
+S3156000ACE000000000000000000000000000000000FE\r
+S3156000ACF000000000000000000000000000000000EE\r
+S3156000AD0000000000000000000000000000000000DD\r
+S3156000AD1000000000000000000000000000000000CD\r
+S3156000AD2000000000000000000000000000000000BD\r
+S3156000AD3000000000000000000000000000000000AD\r
+S3156000AD40000000000000000000000000000000009D\r
+S3156000AD50000000000000000000000000000000008D\r
+S3156000AD60000000000000000000000000000000007D\r
+S3156000AD70000000000000000000000000000000006D\r
+S3156000AD80000000000000000000000000000000005D\r
+S3156000AD90000000000000000000000000000000004D\r
+S3156000ADA0000000000000000000000000000000003D\r
+S3156000ADB0000000000000000000000000000000002D\r
+S3156000ADC0000000000000000000000000000000001D\r
+S3156000ADD0000000000000000000000000000000000D\r
+S3156000ADE000000000000000000000000000000000FD\r
+S3156000ADF000000000000000000000000000000000ED\r
+S3156000AE0000000000000000000000000000000000DC\r
+S3156000AE1000000000000000000000000000000000CC\r
+S3156000AE2000000000000000000000000000000000BC\r
+S3156000AE3000000000000000000000000000000000AC\r
+S3156000AE40000000000000000000000000000000009C\r
+S3156000AE50000000000000000000000000000000008C\r
+S3156000AE60000000000000000000000000000000007C\r
+S3156000AE70000000000000000000000000000000006C\r
+S3156000AE80000000000000000000000000000000005C\r
+S3156000AE90000000000000000000000000000000004C\r
+S3156000AEA0000000000000000000000000000000003C\r
+S3156000AEB0000000000000000000000000000000002C\r
+S3156000AEC0000000000000000000000000000000001C\r
+S3156000AED0000000000000000000000000000000000C\r
+S3156000AEE000000000000000000000000000000000FC\r
+S3156000AEF000000000000000000000000000000000EC\r
+S3156000AF0000000000000000000000000000000000DB\r
+S3156000AF1000000000000000000000000000000000CB\r
+S3156000AF2000000000000000000000000000000000BB\r
+S3156000AF3000000000000000000000000000000000AB\r
+S3156000AF40000000000000000000000000000000009B\r
+S3156000AF50000000000000000000000000000000008B\r
+S3156000AF60000000000000000000000000000000007B\r
+S3156000AF70000000000000000000000000000000006B\r
+S3156000AF80000000000000000000000000000000005B\r
+S3156000AF90000000000000000000000000000000004B\r
+S3156000AFA0000000000000000000000000000000003B\r
+S3156000AFB0000000000000000000000000000000002B\r
+S3156000AFC0000000000000000000000000000000001B\r
+S3156000AFD0000000000000000000000000000000000B\r
+S3156000AFE000000000000000000000000000000000FB\r
+S3156000AFF000000000000000000000000000000000EB\r
+S3156000B00000000000000000000000000000000000DA\r
+S3156000B01000000000000000000000000000000000CA\r
+S3156000B02000000000000000000000000000000000BA\r
+S3156000B03000000000000000000000000000000000AA\r
+S3156000B040000000000000000000000000000000009A\r
+S3156000B050000000000000000000000000000000008A\r
+S3156000B060000000000000000000000000000000007A\r
+S3156000B070000000000000000000000000000000006A\r
+S3156000B080000000000000000000000000000000005A\r
+S3156000B090000000000000000000000000000000004A\r
+S3156000B0A0000000000000000000000000000000003A\r
+S3156000B0B0000000000000000000000000000000002A\r
+S3156000B0C0000000000000000000000000000000001A\r
+S3156000B0D0000000000000000000000000000000000A\r
+S3156000B0E000000000000000000000000000000000FA\r
+S3156000B0F000000000000000000000000000000000EA\r
+S3156000B10000000000000000000000000000000000D9\r
+S3156000B11000000000000000000000000000000000C9\r
+S3156000B12000000000000000000000000000000000B9\r
+S3156000B13000000000000000000000000000000000A9\r
+S3156000B1400000000000000000000000000000000099\r
+S3156000B1500000000000000000000000000000000089\r
+S3156000B1600000000000000000000000000000000079\r
+S3156000B1700000000000000000000000000000000069\r
+S3156000B1800000000000000000000000000000000059\r
+S3156000B1900000000000000000000000000000000049\r
+S3156000B1A00000000000000000000000000000000039\r
+S3156000B1B00000000000000000000000000000000029\r
+S3156000B1C00000000000000000000000000000000019\r
+S3156000B1D00000000000000000000000000000000009\r
+S3156000B1E000000000000000000000000000000000F9\r
+S3156000B1F000000000000000000000000000000000E9\r
+S3156000B20000000000000000000000000000000000D8\r
+S3156000B21000000000000000000000000000000000C8\r
+S3156000B22000000000000000000000000000000000B8\r
+S3156000B23000000000000000000000000000000000A8\r
+S3156000B2400000000000000000000000000000000098\r
+S3156000B2500000000000000000000000000000000088\r
+S3156000B2600000000000000000000000000000000078\r
+S3156000B2700000000000000000000000000000000068\r
+S3156000B2800000000000000000000000000000000058\r
+S3156000B2900000000000000000000000000000000048\r
+S3156000B2A00000000000000000000000000000000038\r
+S3156000B2B00000000000000000000000000000000028\r
+S3156000B2C00000000000000000000000000000000018\r
+S3156000B2D00000000000000000000000000000000008\r
+S3156000B2E000000000000000000000000000000000F8\r
+S3156000B2F000000000000000000000000000000000E8\r
+S3156000B30000000000000000000000000000000000D7\r
+S3156000B31000000000000000000000000000000000C7\r
+S3156000B32000000000000000000000000000000000B7\r
+S3156000B33000000000000000000000000000000000A7\r
+S3156000B3400000000000000000000000000000000097\r
+S3156000B3500000000000000000000000000000000087\r
+S3156000B3600000000000000000000000000000000077\r
+S3156000B3700000000000000000000000000000000067\r
+S3156000B3800000000000000000000000000000000057\r
+S3156000B3900000000000000000000000000000000047\r
+S3156000B3A00000000000000000000000000000000037\r
+S3156000B3B00000000000000000000000000000000027\r
+S3156000B3C00000000000000000000000000000000017\r
+S3156000B3D00000000000000000000000000000000007\r
+S3156000B3E000000000000000000000000000000000F7\r
+S3156000B3F000000000000000000000000000000000E7\r
+S3156000B40000000000000000000000000000000000D6\r
+S3156000B41000000000000000000000000000000000C6\r
+S3156000B42000000000000000000000000000000000B6\r
+S3156000B43000000000000000000000000000000000A6\r
+S3156000B4400000000000000000000000000000000096\r
+S3156000B4500000000000000000000000000000000086\r
+S3156000B4600000000000000000000000000000000076\r
+S3156000B4700000000000000000000000000000000066\r
+S3156000B4800000000000000000000000000000000056\r
+S3156000B4900000000000000000000000000000000046\r
+S3156000B4A00000000000000000000000000000000036\r
+S3156000B4B00000000000000000000000000000000026\r
+S3156000B4C00000000000000000000000000000000016\r
+S3156000B4D00000000000000000000000000000000006\r
+S3156000B4E000000000000000000000000000000000F6\r
+S3156000B4F000000000000000000000000000000000E6\r
+S3156000B50000000000000000000000000000000000D5\r
+S3156000B51000000000000000000000000000000000C5\r
+S3156000B52000000000000000000000000000000000B5\r
+S3156000B53000000000000000000000000000000000A5\r
+S3156000B5400000000000000000000000000000000095\r
+S3156000B5500000000000000000000000000000000085\r
+S3156000B5600000000000000000000000000000000075\r
+S3156000B5700000000000000000000000000000000065\r
+S3156000B5800000000000000000000000000000000055\r
+S3156000B5900000000000000000000000000000000045\r
+S3156000B5A00000000000000000000000000000000035\r
+S3156000B5B00000000000000000000000000000000025\r
+S3156000B5C00000000000000000000000000000000015\r
+S3156000B5D00000000000000000000000000000000005\r
+S3156000B5E000000000000000000000000000000000F5\r
+S3156000B5F000000000000000000000000000000000E5\r
+S3156000B60000000000000000000000000000000000D4\r
+S3156000B61000000000000000000000000000000000C4\r
+S3156000B62000000000000000000000000000000000B4\r
+S3156000B63000000000000000000000000000000000A4\r
+S3156000B6400000000000000000000000000000000094\r
+S3156000B6500000000000000000000000000000000084\r
+S3156000B6600000000000000000000000000000000074\r
+S3156000B6700000000000000000000000000000000064\r
+S3156000B6800000000000000000000000000000000054\r
+S3156000B6900000000000000000000000000000000044\r
+S3156000B6A00000000000000000000000000000000034\r
+S3156000B6B00000000000000000000000000000000024\r
+S3156000B6C00000000000000000000000000000000014\r
+S3156000B6D00000000000000000000000000000000004\r
+S3156000B6E000000000000000000000000000000000F4\r
+S3156000B6F000000000000000000000000000000000E4\r
+S3156000B70000000000000000000000000000000000D3\r
+S3156000B71000000000000000000000000000000000C3\r
+S3156000B72000000000000000000000000000000000B3\r
+S3156000B73000000000000000000000000000000000A3\r
+S3156000B7400000000000000000000000000000000093\r
+S3156000B7500000000000000000000000000000000083\r
+S3156000B7600000000000000000000000000000000073\r
+S3156000B7700000000000000000000000000000000063\r
+S3156000B7800000000000000000000000000000000053\r
+S3156000B7900000000000000000000000000000000043\r
+S3156000B7A00000000000000000000000000000000033\r
+S3156000B7B00000000000000000000000000000000023\r
+S3156000B7C00000000000000000000000000000000013\r
+S3156000B7D00000000000000000000000000000000003\r
+S3156000B7E000000000000000000000000000000000F3\r
+S3156000B7F000000000000000000000000000000000E3\r
+S3156000B80000000000000000000000000000000000D2\r
+S3156000B81000000000000000000000000000000000C2\r
+S3156000B82000000000000000000000000000000000B2\r
+S3156000B83000000000000000000000000000000000A2\r
+S3156000B8400000000000000000000000000000000092\r
+S3156000B8500000000000000000000000000000000082\r
+S3156000B8600000000000000000000000000000000072\r
+S3156000B8700000000000000000000000000000000062\r
+S3156000B8800000000000000000000000000000000052\r
+S3156000B8900000000000000000000000000000000042\r
+S3156000B8A00000000000000000000000000000000032\r
+S3156000B8B00000000000000000000000000000000022\r
+S3156000B8C00000000000000000000000000000000012\r
+S3156000B8D00000000000000000000000000000000002\r
+S3156000B8E000000000000000000000000000000000F2\r
+S3156000B8F000000000000000000000000000000000E2\r
+S3156000B90000000000000000000000000000000000D1\r
+S3156000B91000000000000000000000000000000000C1\r
+S3156000B92000000000000000000000000000000000B1\r
+S3156000B93000000000000000000000000000000000A1\r
+S3156000B9400000000000000000000000000000000091\r
+S3156000B9500000000000000000000000000000000081\r
+S3156000B9600000000000000000000000000000000071\r
+S3156000B9700000000000000000000000000000000061\r
+S3156000B9800000000000000000000000000000000051\r
+S3156000B9900000000000000000000000000000000041\r
+S3156000B9A00000000000000000000000000000000031\r
+S3156000B9B00000000000000000000000000000000021\r
+S3156000B9C00000000000000000000000000000000011\r
+S3156000B9D00000000000000000000000000000000001\r
+S3156000B9E000000000000000000000000000000000F1\r
+S3156000B9F000000000000000000000000000000000E1\r
+S3156000BA0000000000000000000000000000000000D0\r
+S3156000BA1000000000000000000000000000000000C0\r
+S3156000BA2000000000000000000000000000000000B0\r
+S3156000BA3000000000000000000000000000000000A0\r
+S3156000BA400000000000000000000000000000000090\r
+S3156000BA500000000000000000000000000000000080\r
+S3156000BA600000000000000000000000000000000070\r
+S3156000BA700000000000000000000000000000000060\r
+S3156000BA800000000000000000000000000000000050\r
+S3156000BA900000000000000000000000000000000040\r
+S3156000BAA00000000000000000000000000000000030\r
+S3156000BAB00000000000000000000000000000000020\r
+S3156000BAC00000000000000000000000000000000010\r
+S3156000BAD00000000000000000000000000000000000\r
+S3156000BAE000000000000000000000000000000000F0\r
+S3156000BAF000000000000000000000000000000000E0\r
+S3156000BB0000000000000000000000000000000000CF\r
+S3156000BB1000000000000000000000000000000000BF\r
+S3156000BB2000000000000000000000000000000000AF\r
+S3156000BB30000000000000000000000000000000009F\r
+S3156000BB40000000000000000000000000000000008F\r
+S3156000BB50000000000000000000000000000000007F\r
+S3156000BB60000000000000000000000000000000006F\r
+S3156000BB70000000000000000000000000000000005F\r
+S3156000BB80000000000000000000000000000000004F\r
+S3156000BB90000000000000000000000000000000003F\r
+S3156000BBA0000000000000000000000000000000002F\r
+S3156000BBB0000000000000000000000000000000001F\r
+S3156000BBC0000000000000000000000000000000000F\r
+S3156000BBD000000000000000000000000000000000FF\r
+S3156000BBE000000000000000000000000000000000EF\r
+S3156000BBF000000000000000000000000000000000DF\r
+S3156000BC0000000000000000000000000000000000CE\r
+S3156000BC1000000000000000000000000000000000BE\r
+S3156000BC2000000000000000000000000000000000AE\r
+S3156000BC30000000000000000000000000000000009E\r
+S3156000BC40000000000000000000000000000000008E\r
+S3156000BC50000000000000000000000000000000007E\r
+S3156000BC60000000000000000000000000000000006E\r
+S3156000BC70000000000000000000000000000000005E\r
+S3156000BC80000000000000000000000000000000004E\r
+S3156000BC90000000000000000000000000000000003E\r
+S3156000BCA0000000000000000000000000000000002E\r
+S3156000BCB0000000000000000000000000000000001E\r
+S3156000BCC0000000000000000000000000000000000E\r
+S3156000BCD000000000000000000000000000000000FE\r
+S3156000BCE000000000000000000000000000000000EE\r
+S3156000BCF000000000000000000000000000000000DE\r
+S3156000BD0000000000000000000000000000000000CD\r
+S3156000BD1000000000000000000000000000000000BD\r
+S3156000BD2000000000000000000000000000000000AD\r
+S3156000BD30000000000000000000000000000000009D\r
+S3156000BD40000000000000000000000000000000008D\r
+S3156000BD50000000000000000000000000000000007D\r
+S3156000BD60000000000000000000000000000000006D\r
+S3156000BD70000000000000000000000000000000005D\r
+S3156000BD80000000000000000000000000000000004D\r
+S3156000BD90000000000000000000000000000000003D\r
+S3156000BDA0000000000000000000000000000000002D\r
+S3156000BDB0000000000000000000000000000000001D\r
+S3156000BDC0000000000000000000000000000000000D\r
+S3156000BDD000000000000000000000000000000000FD\r
+S3156000BDE000000000000000000000000000000000ED\r
+S3156000BDF000000000000000000000000000000000DD\r
+S3156000BE0000000000000000000000000000000000CC\r
+S3156000BE1000000000000000000000000000000000BC\r
+S3156000BE2000000000000000000000000000000000AC\r
+S3156000BE30000000000000000000000000000000009C\r
+S3156000BE40000000000000000000000000000000008C\r
+S3156000BE50000000000000000000000000000000007C\r
+S3156000BE60000000000000000000000000000000006C\r
+S3156000BE70000000000000000000000000000000005C\r
+S3156000BE80000000000000000000000000000000004C\r
+S3156000BE90000000000000000000000000000000003C\r
+S3156000BEA0000000000000000000000000000000002C\r
+S3156000BEB0000000000000000000000000000000001C\r
+S3156000BEC0000000000000000000000000000000000C\r
+S3156000BED000000000000000000000000000000000FC\r
+S3156000BEE000000000000000000000000000000000EC\r
+S3156000BEF000000000000000000000000000000000DC\r
+S3156000BF0000000000000000000000000000000000CB\r
+S3156000BF1000000000000000000000000000000000BB\r
+S3156000BF2000000000000000000000000000000000AB\r
+S3156000BF30000000000000000000000000000000009B\r
+S3156000BF40000000000000000000000000000000008B\r
+S3156000BF50000000000000000000000000000000007B\r
+S3156000BF60000000000000000000000000000000006B\r
+S3156000BF70000000000000000000000000000000005B\r
+S3156000BF80000000000000000000000000000000004B\r
+S3156000BF90000000000000000000000000000000003B\r
+S3156000BFA0000000000000000000000000000000002B\r
+S3156000BFB0000000000000000000000000000000001B\r
+S3156000BFC0000000000000000000000000000000000B\r
+S3156000BFD000000000000000000000000000000000FB\r
+S3156000BFE000000000000000000000000000000000EB\r
+S3156000BFF000000000000000000000000000000000DB\r
+S3156000C00000000000000000000000000000000000CA\r
+S3156000C01000000000000000000000000000000000BA\r
+S3156000C02000000000000000000000000000000000AA\r
+S3156000C030000000000000000000000000000000009A\r
+S3156000C040000000000000000000000000000000008A\r
+S3156000C050000000000000000000000000000000007A\r
+S3156000C060000000000000000000000000000000006A\r
+S3156000C070000000000000000000000000000000005A\r
+S3156000C080000000000000000000000000000000004A\r
+S3156000C090000000000000000000000000000000003A\r
+S3156000C0A0000000000000000000000000000000002A\r
+S3156000C0B0000000000000000000000000000000001A\r
+S3156000C0C0000000000000000000000000000000000A\r
+S3156000C0D000000000000000000000000000000000FA\r
+S3156000C0E000000000000000000000000000000000EA\r
+S3156000C0F000000000000000000000000000000000DA\r
+S3156000C10000000000000000000000000000000000C9\r
+S3156000C11000000000000000000000000000000000B9\r
+S3156000C12000000000000000000000000000000000A9\r
+S3156000C1300000000000000000000000000000000099\r
+S3156000C1400000000000000000000000000000000089\r
+S3156000C1500000000000000000000000000000000079\r
+S3156000C1600000000000000000000000000000000069\r
+S3156000C1700000000000000000000000000000000059\r
+S3156000C1800000000000000000000000000000000049\r
+S3156000C1900000000000000000000000000000000039\r
+S3156000C1A00000000000000000000000000000000029\r
+S3156000C1B00000000000000000000000000000000019\r
+S3156000C1C00000000000000000000000000000000009\r
+S3156000C1D000000000000000000000000000000000F9\r
+S3156000C1E000000000000000000000000000000000E9\r
+S3156000C1F000000000000000000000000000000000D9\r
+S3156000C20000000000000000000000000000000000C8\r
+S3156000C21000000000000000000000000000000000B8\r
+S3156000C22000000000000000000000000000000000A8\r
+S3156000C2300000000000000000000000000000000098\r
+S3156000C2400000000000000000000000000000000088\r
+S3156000C2500000000000000000000000000000000078\r
+S3156000C2600000000000000000000000000000000068\r
+S3156000C2700000000000000000000000000000000058\r
+S3156000C2800000000000000000000000000000000048\r
+S3156000C2900000000000000000000000000000000038\r
+S3156000C2A00000000000000000000000000000000028\r
+S3156000C2B00000000000000000000000000000000018\r
+S3156000C2C00000000000000000000000000000000008\r
+S3156000C2D000000000000000000000000000000000F8\r
+S3156000C2E000000000000000000000000000000000E8\r
+S3156000C2F000000000000000000000000000000000D8\r
+S3156000C30000000000000000000000000000000000C7\r
+S3156000C31000000000000000000000000000000000B7\r
+S3156000C32000000000000000000000000000000000A7\r
+S3156000C3300000000000000000000000000000000097\r
+S3156000C3400000000000000000000000000000000087\r
+S3156000C3500000000000000000000000000000000077\r
+S3156000C3600000000000000000000000000000000067\r
+S3156000C3700000000000000000000000000000000057\r
+S3156000C3800000000000000000000000000000000047\r
+S3156000C3900000000000000000000000000000000037\r
+S3156000C3A00000000000000000000000000000000027\r
+S3156000C3B00000000000000000000000000000000017\r
+S3156000C3C00000000000000000000000000000000007\r
+S3156000C3D000000000000000000000000000000000F7\r
+S3156000C3E000000000000000000000000000000000E7\r
+S3156000C3F000000000000000000000000000000000D7\r
+S3156000C40000000000000000000000000000000000C6\r
+S3156000C41000000000000000000000000000000000B6\r
+S3156000C42000000000000000000000000000000000A6\r
+S3156000C4300000000000000000000000000000000096\r
+S3156000C4400000000000000000000000000000000086\r
+S3156000C4500000000000000000000000000000000076\r
+S3156000C4600000000000000000000000000000000066\r
+S3156000C4700000000000000000000000000000000056\r
+S3156000C4800000000000000000000000000000000046\r
+S3156000C4900000000000000000000000000000000036\r
+S3156000C4A00000000000000000000000000000000026\r
+S3156000C4B00000000000000000000000000000000016\r
+S3156000C4C00000000000000000000000000000000006\r
+S3156000C4D000000000000000000000000000000000F6\r
+S3156000C4E000000000000000000000000000000000E6\r
+S3156000C4F000000000000000000000000000000000D6\r
+S3156000C50000000000000000000000000000000000C5\r
+S3156000C51000000000000000000000000000000000B5\r
+S3156000C52000000000000000000000000000000000A5\r
+S3156000C5300000000000000000000000000000000095\r
+S3156000C5400000000000000000000000000000000085\r
+S3156000C5500000000000000000000000000000000075\r
+S3156000C5600000000000000000000000000000000065\r
+S3156000C5700000000000000000000000000000000055\r
+S3156000C5800000000000000000000000000000000045\r
+S3156000C5900000000000000000000000000000000035\r
+S3156000C5A00000000000000000000000000000000025\r
+S3156000C5B00000000000000000000000000000000015\r
+S3156000C5C00000000000000000000000000000000005\r
+S3156000C5D000000000000000000000000000000000F5\r
+S3156000C5E000000000000000000000000000000000E5\r
+S3156000C5F000000000000000000000000000000000D5\r
+S3156000C60000000000000000000000000000000000C4\r
+S3156000C61000000000000000000000000000000000B4\r
+S3156000C62000000000000000000000000000000000A4\r
+S3156000C6300000000000000000000000000000000094\r
+S3156000C6400000000000000000000000000000000084\r
+S3156000C6500000000000000000000000000000000074\r
+S3156000C6600000000000000000000000000000000064\r
+S3156000C6700000000000000000000000000000000054\r
+S3156000C6800000000000000000000000000000000044\r
+S3156000C6900000000000000000000000000000000034\r
+S3156000C6A00000000000000000000000000000000024\r
+S3156000C6B00000000000000000000000000000000014\r
+S3156000C6C00000000000000000000000000000000004\r
+S3156000C6D000000000000000000000000000000000F4\r
+S3156000C6E000000000000000000000000000000000E4\r
+S3156000C6F000000000000000000000000000000000D4\r
+S3156000C70000000000000000000000000000000000C3\r
+S3156000C71000000000000000000000000000000000B3\r
+S3156000C72000000000000000000000000000000000A3\r
+S3156000C7300000000000000000000000000000000093\r
+S3156000C7400000000000000000000000000000000083\r
+S3156000C7500000000000000000000000000000000073\r
+S3156000C7600000000000000000000000000000000063\r
+S3156000C7700000000000000000000000000000000053\r
+S3156000C7800000000000000000000000000000000043\r
+S3156000C7900000000000000000000000000000000033\r
+S3156000C7A00000000000000000000000000000000023\r
+S3156000C7B00000000000000000000000000000000013\r
+S3156000C7C00000000000000000000000000000000003\r
+S3156000C7D000000000000000000000000000000000F3\r
+S3156000C7E000000000000000000000000000000000E3\r
+S3156000C7F000000000000000000000000000000000D3\r
+S3156000C80000000000000000000000000000000000C2\r
+S3156000C81000000000000000000000000000000000B2\r
+S3156000C82000000000000000000000000000000000A2\r
+S3156000C8300000000000000000000000000000000092\r
+S3156000C8400000000000000000000000000000000082\r
+S3156000C8500000000000000000000000000000000072\r
+S3156000C8600000000000000000000000000000000062\r
+S3156000C8700000000000000000000000000000000052\r
+S3156000C8800000000000000000000000000000000042\r
+S3156000C8900000000000000000000000000000000032\r
+S3156000C8A00000000000000000000000000000000022\r
+S3156000C8B00000000000000000000000000000000012\r
+S3156000C8C00000000000000000000000000000000002\r
+S3156000C8D000000000000000000000000000000000F2\r
+S3156000C8E000000000000000000000000000000000E2\r
+S3156000C8F000000000000000000000000000000000D2\r
+S3156000C90000000000000000000000000000000000C1\r
+S3156000C91000000000000000000000000000000000B1\r
+S3156000C92000000000000000000000000000000000A1\r
+S3156000C9300000000000000000000000000000000091\r
+S3156000C9400000000000000000000000000000000081\r
+S3156000C9500000000000000000000000000000000071\r
+S3156000C9600000000000000000000000000000000061\r
+S3156000C9700000000000000000000000000000000051\r
+S3156000C9800000000000000000000000000000000041\r
+S3156000C9900000000000000000000000000000000031\r
+S3156000C9A00000000000000000000000000000000021\r
+S3156000C9B00000000000000000000000000000000011\r
+S3156000C9C00000000000000000000000000000000001\r
+S3156000C9D000000000000000000000000000000000F1\r
+S3156000C9E000000000000000000000000000000000E1\r
+S3156000C9F000000000000000000000000000000000D1\r
+S3156000CA0000000000000000000000000000000000C0\r
+S3156000CA1000000000000000000000000000000000B0\r
+S3156000CA2000000000000000000000000000000000A0\r
+S3156000CA300000000000000000000000000000000090\r
+S3156000CA400000000000000000000000000000000080\r
+S3156000CA500000000000000000000000000000000070\r
+S3156000CA600000000000000000000000000000000060\r
+S3156000CA700000000000000000000000000000000050\r
+S3156000CA800000000000000000000000000000000040\r
+S3156000CA900000000000000000000000000000000030\r
+S3156000CAA00000000000000000000000000000000020\r
+S3156000CAB00000000000000000000000000000000010\r
+S3156000CAC00000000000000000000000000000000000\r
+S3156000CAD000000000000000000000000000000000F0\r
+S3156000CAE000000000000000000000000000000000E0\r
+S3156000CAF000000000000000000000000000000000D0\r
+S3156000CB0000000000000000000000000000000000BF\r
+S3156000CB1000000000000000000000000000000000AF\r
+S3156000CB20000000000000000000000000000000009F\r
+S3156000CB30000000000000000000000000000000008F\r
+S3156000CB40000000000000000000000000000000007F\r
+S3156000CB50000000000000000000000000000000006F\r
+S3156000CB60000000000000000000000000000000005F\r
+S3156000CB70000000000000000000000000000000004F\r
+S3156000CB80000000000000000000000000000000003F\r
+S3156000CB90000000000000000000000000000000002F\r
+S3156000CBA0000000000000000000000000000000001F\r
+S3156000CBB0000000000000000000000000000000000F\r
+S3156000CBC000000000000000000000000000000000FF\r
+S3156000CBD000000000000000000000000000000000EF\r
+S3156000CBE000000000000000000000000000000000DF\r
+S3156000CBF000000000000000000000000000000000CF\r
+S3156000CC0000000000000000000000000000000000BE\r
+S3156000CC1000000000000000000000000000000000AE\r
+S3156000CC20000000000000000000000000000000009E\r
+S3156000CC30000000000000000000000000000000008E\r
+S3156000CC40000000000000000000000000000000007E\r
+S3156000CC50000000000000000000000000000000006E\r
+S3156000CC60000000000000000000000000000000005E\r
+S3156000CC70000000000000000000000000000000004E\r
+S3156000CC80000000000000000000000000000000003E\r
+S3156000CC90000000000000000000000000000000002E\r
+S3156000CCA0000000000000000000000000000000001E\r
+S3156000CCB0000000000000000000000000000000000E\r
+S3156000CCC000000000000000000000000000000000FE\r
+S3156000CCD000000000000000000000000000000000EE\r
+S3156000CCE000000000000000000000000000000000DE\r
+S3156000CCF000000000000000000000000000000000CE\r
+S3156000CD0000000000000000000000000000000000BD\r
+S3156000CD1000000000000000000000000000000000AD\r
+S3156000CD20000000000000000000000000000000009D\r
+S3156000CD30000000000000000000000000000000008D\r
+S3156000CD40000000000000000000000000000000007D\r
+S3156000CD50000000000000000000000000000000006D\r
+S3156000CD60000000000000000000000000000000005D\r
+S3156000CD70000000000000000000000000000000004D\r
+S3156000CD80000000000000000000000000000000003D\r
+S3156000CD90000000000000000000000000000000002D\r
+S3156000CDA0000000000000000000000000000000001D\r
+S3156000CDB0000000000000000000000000000000000D\r
+S3156000CDC000000000000000000000000000000000FD\r
+S3156000CDD000000000000000000000000000000000ED\r
+S3156000CDE000000000000000000000000000000000DD\r
+S3156000CDF000000000000000000000000000000000CD\r
+S3156000CE0000000000000000000000000000000000BC\r
+S3156000CE1000000000000000000000000000000000AC\r
+S3156000CE20000000000000000000000000000000009C\r
+S3156000CE30000000000000000000000000000000008C\r
+S3156000CE40000000000000000000000000000000007C\r
+S3156000CE50000000000000000000000000000000006C\r
+S3156000CE60000000000000000000000000000000005C\r
+S3156000CE70000000000000000000000000000000004C\r
+S3156000CE80000000000000000000000000000000003C\r
+S3156000CE90000000000000000000000000000000002C\r
+S3156000CEA0000000000000000000000000000000001C\r
+S3156000CEB0000000000000000000000000000000000C\r
+S3156000CEC000000000000000000000000000000000FC\r
+S3156000CED000000000000000000000000000000000EC\r
+S3156000CEE000000000000000000000000000000000DC\r
+S3156000CEF000000000000000000000000000000000CC\r
+S3156000CF0000000000000000000000000000000000BB\r
+S3156000CF1000000000000000000000000000000000AB\r
+S3156000CF20000000000000000000000000000000009B\r
+S3156000CF30000000000000000000000000000000008B\r
+S3156000CF40000000000000000000000000000000007B\r
+S3156000CF50000000000000000000000000000000006B\r
+S3156000CF60000000000000000000000000000000005B\r
+S3156000CF70000000000000000000000000000000004B\r
+S3156000CF80000000000000000000000000000000003B\r
+S3156000CF90000000000000000000000000000000002B\r
+S3156000CFA0000000000000000000000000000000001B\r
+S3156000CFB0000000000000000000000000000000000B\r
+S3156000CFC000000000000000000000000000000000FB\r
+S3156000CFD000000000000000000000000000000000EB\r
+S3156000CFE000000000000000000000000000000000DB\r
+S3156000CFF000000000000000000000000000000000CB\r
+S3156000D00000000000000000000000000000000000BA\r
+S3156000D01000000000000000000000000000000000AA\r
+S3156000D020000000000000000000000000000000009A\r
+S3156000D030000000000000000000000000000000008A\r
+S3156000D040000000000000000000000000000000007A\r
+S3156000D050000000000000000000000000000000006A\r
+S3156000D060000000000000000000000000000000005A\r
+S3156000D070000000000000000000000000000000004A\r
+S3156000D080000000000000000000000000000000003A\r
+S3156000D090000000000000000000000000000000002A\r
+S3156000D0A0000000000000000000000000000000001A\r
+S3156000D0B0000000000000000000000000000000000A\r
+S3156000D0C000000000000000000000000000000000FA\r
+S3156000D0D000000000000000000000000000000000EA\r
+S3156000D0E000000000000000000000000000000000DA\r
+S3156000D0F000000000000000000000000000000000CA\r
+S3156000D10000000000000000000000000000000000B9\r
+S3156000D11000000000000000000000000000000000A9\r
+S3156000D1200000000000000000000000000000000099\r
+S3156000D1300000000000000000000000000000000089\r
+S3156000D1400000000000000000000000000000000079\r
+S3156000D1500000000000000000000000000000000069\r
+S3156000D1600000000000000000000000000000000059\r
+S3156000D1700000000000000000000000000000000049\r
+S3156000D1800000000000000000000000000000000039\r
+S3156000D1900000000000000000000000000000000029\r
+S3156000D1A00000000000000000000000000000000019\r
+S3156000D1B00000000000000000000000000000000009\r
+S3156000D1C000000000000000000000000000000000F9\r
+S3156000D1D000000000000000000000000000000000E9\r
+S3156000D1E000000000000000000000000000000000D9\r
+S3156000D1F000000000000000000000000000000000C9\r
+S3156000D20000000000000000000000000000000000B8\r
+S3156000D21000000000000000000000000000000000A8\r
+S3156000D2200000000000000000000000000000000098\r
+S3156000D2300000000000000000000000000000000088\r
+S3156000D2400000000000000000000000000000000078\r
+S3156000D2500000000000000000000000000000000068\r
+S3156000D2600000000000000000000000000000000058\r
+S3156000D2700000000000000000000000000000000048\r
+S3156000D2800000000000000000000000000000000038\r
+S3156000D2900000000000000000000000000000000028\r
+S3156000D2A00000000000000000000000000000000018\r
+S3156000D2B00000000000000000000000000000000008\r
+S3156000D2C000000000000000000000000000000000F8\r
+S3156000D2D000000000000000000000000000000000E8\r
+S3156000D2E000000000000000000000000000000000D8\r
+S3156000D2F000000000000000000000000000000000C8\r
+S3156000D30000000000000000000000000000000000B7\r
+S3156000D31000000000000000000000000000000000A7\r
+S3156000D3200000000000000000000000000000000097\r
+S3156000D3300000000000000000000000000000000087\r
+S3156000D3400000000000000000000000000000000077\r
+S3156000D3500000000000000000000000000000000067\r
+S3156000D3600000000000000000000000000000000057\r
+S3156000D3700000000000000000000000000000000047\r
+S3156000D3800000000000000000000000000000000037\r
+S3156000D3900000000000000000000000000000000027\r
+S3156000D3A00000000000000000000000000000000017\r
+S3156000D3B00000000000000000000000000000000007\r
+S3156000D3C000000000000000000000000000000000F7\r
+S3156000D3D000000000000000000000000000000000E7\r
+S3156000D3E000000000000000000000000000000000D7\r
+S3156000D3F000000000000000000000000000000000C7\r
+S3156000D40000000000000000000000000000000000B6\r
+S3156000D41000000000000000000000000000000000A6\r
+S3156000D4200000000000000000000000000000000096\r
+S3156000D4300000000000000000000000000000000086\r
+S3156000D4400000000000000000000000000000000076\r
+S3156000D4500000000000000000000000000000000066\r
+S3156000D4600000000000000000000000000000000056\r
+S3156000D4700000000000000000000000000000000046\r
+S3156000D4800000000000000000000000000000000036\r
+S3156000D4900000000000000000000000000000000026\r
+S3156000D4A00000000000000000000000000000000016\r
+S3156000D4B00000000000000000000000000000000006\r
+S3156000D4C000000000000000000000000000000000F6\r
+S3156000D4D000000000000000000000000000000000E6\r
+S3156000D4E000000000000000000000000000000000D6\r
+S3156000D4F000000000000000000000000000000000C6\r
+S3156000D50000000000000000000000000000000000B5\r
+S3156000D51000000000000000000000000000000000A5\r
+S3156000D5200000000000000000000000000000000095\r
+S3156000D5300000000000000000000000000000000085\r
+S3156000D5400000000000000000000000000000000075\r
+S3156000D5500000000000000000000000000000000065\r
+S3156000D5600000000000000000000000000000000055\r
+S3156000D5700000000000000000000000000000000045\r
+S3156000D5800000000000000000000000000000000035\r
+S3156000D5900000000000000000000000000000000025\r
+S3156000D5A00000000000000000000000000000000015\r
+S3156000D5B00000000000000000000000000000000005\r
+S3156000D5C000000000000000000000000000000000F5\r
+S3156000D5D000000000000000000000000000000000E5\r
+S3156000D5E000000000000000000000000000000000D5\r
+S3156000D5F000000000000000000000000000000000C5\r
+S3156000D60000000000000000000000000000000000B4\r
+S3156000D61000000000000000000000000000000000A4\r
+S3156000D6200000000000000000000000000000000094\r
+S3156000D6300000000000000000000000000000000084\r
+S3156000D6400000000000000000000000000000000074\r
+S3156000D6500000000000000000000000000000000064\r
+S3156000D6600000000000000000000000000000000054\r
+S3156000D6700000000000000000000000000000000044\r
+S3156000D6800000000000000000000000000000000034\r
+S3156000D6900000000000000000000000000000000024\r
+S3156000D6A00000000000000000000000000000000014\r
+S3156000D6B00000000000000000000000000000000004\r
+S3156000D6C000000000000000000000000000000000F4\r
+S3156000D6D000000000000000000000000000000000E4\r
+S3156000D6E000000000000000000000000000000000D4\r
+S3156000D6F000000000000000000000000000000000C4\r
+S3156000D70000000000000000000000000000000000B3\r
+S3156000D71000000000000000000000000000000000A3\r
+S3156000D7200000000000000000000000000000000093\r
+S3156000D7300000000000000000000000000000000083\r
+S3156000D7400000000000000000000000000000000073\r
+S3156000D7500000000000000000000000000000000063\r
+S3156000D7600000000000000000000000000000000053\r
+S3156000D7700000000000000000000000000000000043\r
+S3156000D7800000000000000000000000000000000033\r
+S3156000D7900000000000000000000000000000000023\r
+S3156000D7A00000000000000000000000000000000013\r
+S3156000D7B00000000000000000000000000000000003\r
+S3156000D7C000000000000000000000000000000000F3\r
+S3156000D7D000000000000000000000000000000000E3\r
+S3156000D7E000000000000000000000000000000000D3\r
+S3156000D7F000000000000000000000000000000000C3\r
+S3156000D80000000000000000000000000000000000B2\r
+S3156000D81000000000000000000000000000000000A2\r
+S3156000D8200000000000000000000000000000000092\r
+S3156000D8300000000000000000000000000000000082\r
+S3156000D8400000000000000000000000000000000072\r
+S3156000D8500000000000000000000000000000000062\r
+S3156000D8600000000000000000000000000000000052\r
+S3156000D8700000000000000000000000000000000042\r
+S3156000D8800000000000000000000000000000000032\r
+S3156000D8900000000000000000000000000000000022\r
+S3156000D8A00000000000000000000000000000000012\r
+S3156000D8B00000000000000000000000000000000002\r
+S3156000D8C000000000000000000000000000000000F2\r
+S3156000D8D000000000000000000000000000000000E2\r
+S3156000D8E000000000000000000000000000000000D2\r
+S3156000D8F000000000000000000000000000000000C2\r
+S3156000D90000000000000000000000000000000000B1\r
+S3156000D91000000000000000000000000000000000A1\r
+S3156000D9200000000000000000000000000000000091\r
+S3156000D9300000000000000000000000000000000081\r
+S3156000D9400000000000000000000000000000000071\r
+S3156000D9500000000000000000000000000000000061\r
+S3156000D9600000000000000000000000000000000051\r
+S3156000D9700000000000000000000000000000000041\r
+S3156000D9800000000000000000000000000000000031\r
+S3156000D9900000000000000000000000000000000021\r
+S3156000D9A00000000000000000000000000000000011\r
+S3156000D9B00000000000000000000000000000000001\r
+S3156000D9C000000000000000000000000000000000F1\r
+S3156000D9D000000000000000000000000000000000E1\r
+S3156000D9E000000000000000000000000000000000D1\r
+S3156000D9F000000000000000000000000000000000C1\r
+S3156000DA0000000000000000000000000000000000B0\r
+S3156000DA1000000000000000000000000000000000A0\r
+S3156000DA200000000000000000000000000000000090\r
+S3156000DA300000000000000000000000000000000080\r
+S3156000DA400000000000000000000000000000000070\r
+S3156000DA500000000000000000000000000000000060\r
+S3156000DA600000000000000000000000000000000050\r
+S3156000DA700000000000000000000000000000000040\r
+S3156000DA800000000000000000000000000000000030\r
+S3156000DA900000000000000000000000000000000020\r
+S3156000DAA00000000000000000000000000000000010\r
+S3156000DAB00000000000000000000000000000000000\r
+S3156000DAC000000000000000000000000000000000F0\r
+S3156000DAD000000000000000000000000000000000E0\r
+S3156000DAE000000000000000000000000000000000D0\r
+S3156000DAF000000000000000000000000000000000C0\r
+S3156000DB0000000000000000000000000000000000AF\r
+S3156000DB10000000000000000000000000000000009F\r
+S3156000DB20000000000000000000000000000000008F\r
+S3156000DB30000000000000000000000000000000007F\r
+S3156000DB40000000000000000000000000000000006F\r
+S3156000DB50000000000000000000000000000000005F\r
+S3156000DB60000000000000000000000000000000004F\r
+S3156000DB70000000000000000000000000000000003F\r
+S3156000DB80000000000000000000000000000000002F\r
+S3156000DB90000000000000000000000000000000001F\r
+S3156000DBA0000000000000000000000000000000000F\r
+S3156000DBB000000000000000000000000000000000FF\r
+S3156000DBC000000000000000000000000000000000EF\r
+S3156000DBD000000000000000000000000000000000DF\r
+S3156000DBE000000000000000000000000000000000CF\r
+S3156000DBF000000000000000000000000000000000BF\r
+S3156000DC0000000000000000000000000000000000AE\r
+S3156000DC10000000000000000000000000000000009E\r
+S3156000DC20000000000000000000000000000000008E\r
+S3156000DC30000000000000000000000000000000007E\r
+S3156000DC40000000000000000000000000000000006E\r
+S3156000DC50000000000000000000000000000000005E\r
+S3156000DC60000000000000000000000000000000004E\r
+S3156000DC70000000000000000000000000000000003E\r
+S3156000DC80000000000000000000000000000000002E\r
+S3156000DC90000000000000000000000000000000001E\r
+S3156000DCA0000000000000000000000000000000000E\r
+S3156000DCB000000000000000000000000000000000FE\r
+S3156000DCC000000000000000000000000000000000EE\r
+S3156000DCD000000000000000000000000000000000DE\r
+S3156000DCE000000000000000000000000000000000CE\r
+S3156000DCF000000000000000000000000000000000BE\r
+S3156000DD0000000000000000000000000000000000AD\r
+S3156000DD10000000000000000000000000000000009D\r
+S3156000DD20000000000000000000000000000000008D\r
+S3156000DD30000000000000000000000000000000007D\r
+S3156000DD40000000000000000000000000000000006D\r
+S3156000DD50000000000000000000000000000000005D\r
+S3156000DD60000000000000000000000000000000004D\r
+S3156000DD70000000000000000000000000000000003D\r
+S3156000DD80000000000000000000000000000000002D\r
+S3156000DD90000000000000000000000000000000001D\r
+S3156000DDA0000000000000000000000000000000000D\r
+S3156000DDB000000000000000000000000000000000FD\r
+S3156000DDC000000000000000000000000000000000ED\r
+S3156000DDD000000000000000000000000000000000DD\r
+S3156000DDE000000000000000000000000000000000CD\r
+S3156000DDF000000000000000000000000000000000BD\r
+S3156000DE0000000000000000000000000000000000AC\r
+S3156000DE10000000000000000000000000000000009C\r
+S3156000DE20000000000000000000000000000000008C\r
+S3156000DE30000000000000000000000000000000007C\r
+S3156000DE40000000000000000000000000000000006C\r
+S3156000DE50000000000000000000000000000000005C\r
+S3156000DE60000000000000000000000000000000004C\r
+S3156000DE70000000000000000000000000000000003C\r
+S3156000DE80000000000000000000000000000000002C\r
+S3156000DE90000000000000000000000000000000001C\r
+S3156000DEA0000000000000000000000000000000000C\r
+S3156000DEB000000000000000000000000000000000FC\r
+S3156000DEC000000000000000000000000000000000EC\r
+S3156000DED000000000000000000000000000000000DC\r
+S3156000DEE000000000000000000000000000000000CC\r
+S3156000DEF000000000000000000000000000000000BC\r
+S3156000DF0000000000000000000000000000000000AB\r
+S3156000DF10000000000000000000000000000000009B\r
+S3156000DF20000000000000000000000000000000008B\r
+S3156000DF30000000000000000000000000000000007B\r
+S3156000DF40000000000000000000000000000000006B\r
+S3156000DF50000000000000000000000000000000005B\r
+S3156000DF60000000000000000000000000000000004B\r
+S3156000DF70000000000000000000000000000000003B\r
+S3156000DF80000000000000000000000000000000002B\r
+S3156000DF90000000000000000000000000000000001B\r
+S3156000DFA0000000000000000000000000000000000B\r
+S3156000DFB000000000000000000000000000000000FB\r
+S3156000DFC000000000000000000000000000000000EB\r
+S3156000DFD000000000000000000000000000000000DB\r
+S3156000DFE000000000000000000000000000000000CB\r
+S3156000DFF000000000000000000000000000000000BB\r
+S3156000E00000000000000000000000000000000000AA\r
+S3156000E010000000000000000000000000000000009A\r
+S3156000E020000000000000000000000000000000008A\r
+S3156000E030000000000000000000000000000000007A\r
+S3156000E040000000000000000000000000000000006A\r
+S3156000E050000000000000000000000000000000005A\r
+S3156000E060000000000000000000000000000000004A\r
+S3156000E070000000000000000000000000000000003A\r
+S3156000E080000000000000000000000000000000002A\r
+S3156000E090000000000000000000000000000000001A\r
+S3156000E0A0000000000000000000000000000000000A\r
+S3156000E0B000000000000000000000000000000000FA\r
+S3156000E0C000000000000000000000000000000000EA\r
+S3156000E0D000000000000000000000000000000000DA\r
+S3156000E0E000000000000000000000000000000000CA\r
+S3156000E0F000000000000000000000000000000000BA\r
+S3156000E10000000000000000000000000000000000A9\r
+S3156000E1100000000000000000000000000000000099\r
+S3156000E1200000000000000000000000000000000089\r
+S3156000E1300000000000000000000000000000000079\r
+S3156000E1400000000000000000000000000000000069\r
+S3156000E1500000000000000000000000000000000059\r
+S3156000E1600000000000000000000000000000000049\r
+S3156000E1700000000000000000000000000000000039\r
+S3156000E1800000000000000000000000000000000029\r
+S3156000E1900000000000000000000000000000000019\r
+S3156000E1A00000000000000000000000000000000009\r
+S3156000E1B000000000000000000000000000000000F9\r
+S3156000E1C000000000000000000000000000000000E9\r
+S3156000E1D000000000000000000000000000000000D9\r
+S3156000E1E000000000000000000000000000000000C9\r
+S3156000E1F000000000000000000000000000000000B9\r
+S3156000E20000000000000000000000000000000000A8\r
+S3156000E2100000000000000000000000000000000098\r
+S3156000E2200000000000000000000000000000000088\r
+S3156000E2300000000000000000000000000000000078\r
+S3156000E2400000000000000000000000000000000068\r
+S3156000E2500000000000000000000000000000000058\r
+S3156000E2600000000000000000000000000000000048\r
+S3156000E2700000000000000000000000000000000038\r
+S3156000E2800000000000000000000000000000000028\r
+S3156000E2900000000000000000000000000000000018\r
+S3156000E2A00000000000000000000000000000000008\r
+S3156000E2B000000000000000000000000000000000F8\r
+S3156000E2C000000000000000000000000000000000E8\r
+S3156000E2D000000000000000000000000000000000D8\r
+S3156000E2E000000000000000000000000000000000C8\r
+S3156000E2F000000000000000000000000000000000B8\r
+S3156000E30000000000000000000000000000000000A7\r
+S3156000E3100000000000000000000000000000000097\r
+S3156000E3200000000000000000000000000000000087\r
+S3156000E3300000000000000000000000000000000077\r
+S3156000E3400000000000000000000000000000000067\r
+S3156000E3500000000000000000000000000000000057\r
+S3156000E3600000000000000000000000000000000047\r
+S3156000E3700000000000000000000000000000000037\r
+S3156000E3800000000000000000000000000000000027\r
+S3156000E3900000000000000000000000000000000017\r
+S3156000E3A00000000000000000000000000000000007\r
+S3156000E3B000000000000000000000000000000000F7\r
+S3156000E3C000000000000000000000000000000000E7\r
+S3156000E3D000000000000000000000000000000000D7\r
+S3156000E3E000000000000000000000000000000000C7\r
+S3156000E3F000000000000000000000000000000000B7\r
+S3156000E40000000000000000000000000000000000A6\r
+S3156000E4100000000000000000000000000000000096\r
+S3156000E4200000000000000000000000000000000086\r
+S3156000E4300000000000000000000000000000000076\r
+S3156000E4400000000000000000000000000000000066\r
+S3156000E4500000000000000000000000000000000056\r
+S3156000E4600000000000000000000000000000000046\r
+S3156000E4700000000000000000000000000000000036\r
+S3156000E4800000000000000000000000000000000026\r
+S3156000E4900000000000000000000000000000000016\r
+S3156000E4A00000000000000000000000000000000006\r
+S3156000E4B000000000000000000000000000000000F6\r
+S3156000E4C000000000000000000000000000000000E6\r
+S3156000E4D000000000000000000000000000000000D6\r
+S3156000E4E000000000000000000000000000000000C6\r
+S3156000E4F000000000000000000000000000000000B6\r
+S3156000E50000000000000000000000000000000000A5\r
+S3156000E5100000000000000000000000000000000095\r
+S3156000E5200000000000000000000000000000000085\r
+S3156000E5300000000000000000000000000000000075\r
+S3156000E5400000000000000000000000000000000065\r
+S3156000E5500000000000000000000000000000000055\r
+S3156000E5600000000000000000000000000000000045\r
+S3156000E5700000000000000000000000000000000035\r
+S3156000E5800000000000000000000000000000000025\r
+S3156000E5900000000000000000000000000000000015\r
+S3156000E5A00000000000000000000000000000000005\r
+S3156000E5B000000000000000000000000000000000F5\r
+S3156000E5C000000000000000000000000000000000E5\r
+S3156000E5D000000000000000000000000000000000D5\r
+S3156000E5E000000000000000000000000000000000C5\r
+S3156000E5F000000000000000000000000000000000B5\r
+S3156000E60000000000000000000000000000000000A4\r
+S3156000E6100000000000000000000000000000000094\r
+S3156000E6200000000000000000000000000000000084\r
+S3156000E6300000000000000000000000000000000074\r
+S3156000E6400000000000000000000000000000000064\r
+S3156000E6500000000000000000000000000000000054\r
+S3156000E6600000000000000000000000000000000044\r
+S3156000E6700000000000000000000000000000000034\r
+S3156000E6800000000000000000000000000000000024\r
+S3156000E6900000000000000000000000000000000014\r
+S3156000E6A00000000000000000000000000000000004\r
+S3156000E6B000000000000000000000000000000000F4\r
+S3156000E6C000000000000000000000000000000000E4\r
+S3156000E6D000000000000000000000000000000000D4\r
+S3156000E6E000000000000000000000000000000000C4\r
+S3156000E6F000000000000000000000000000000000B4\r
+S3156000E70000000000000000000000000000000000A3\r
+S3156000E7100000000000000000000000000000000093\r
+S3156000E7200000000000000000000000000000000083\r
+S3156000E7300000000000000000000000000000000073\r
+S3156000E7400000000000000000000000000000000063\r
+S3156000E7500000000000000000000000000000000053\r
+S3156000E7600000000000000000000000000000000043\r
+S3156000E7700000000000000000000000000000000033\r
+S3156000E7800000000000000000000000000000000023\r
+S3156000E7900000000000000000000000000000000013\r
+S3156000E7A00000000000000000000000000000000003\r
+S3156000E7B000000000000000000000000000000000F3\r
+S3156000E7C000000000000000000000000000000000E3\r
+S3156000E7D000000000000000000000000000000000D3\r
+S3156000E7E000000000000000000000000000000000C3\r
+S3156000E7F000000000000000000000000000000000B3\r
+S3156000E80000000000000000000000000000000000A2\r
+S3156000E8100000000000000000000000000000000092\r
+S3156000E8200000000000000000000000000000000082\r
+S3156000E8300000000000000000000000000000000072\r
+S3156000E8400000000000000000000000000000000062\r
+S3156000E8500000000000000000000000000000000052\r
+S3156000E8600000000000000000000000000000000042\r
+S3156000E8700000000000000000000000000000000032\r
+S3156000E8800000000000000000000000000000000022\r
+S3156000E8900000000000000000000000000000000012\r
+S3156000E8A00000000000000000000000000000000002\r
+S3156000E8B000000000000000000000000000000000F2\r
+S3156000E8C000000000000000000000000000000000E2\r
+S3156000E8D000000000000000000000000000000000D2\r
+S3156000E8E000000000000000000000000000000000C2\r
+S3156000E8F000000000000000000000000000000000B2\r
+S3156000E90000000000000000000000000000000000A1\r
+S3156000E9100000000000000000000000000000000091\r
+S3156000E9200000000000000000000000000000000081\r
+S3156000E9300000000000000000000000000000000071\r
+S3156000E9400000000000000000000000000000000061\r
+S3156000E9500000000000000000000000000000000051\r
+S3156000E9600000000000000000000000000000000041\r
+S3156000E9700000000000000000000000000000000031\r
+S3156000E9800000000000000000000000000000000021\r
+S3156000E9900000000000000000000000000000000011\r
+S3156000E9A00000000000000000000000000000000001\r
+S3156000E9B000000000000000000000000000000000F1\r
+S3156000E9C000000000000000000000000000000000E1\r
+S3156000E9D000000000000000000000000000000000D1\r
+S3156000E9E000000000000000000000000000000000C1\r
+S3156000E9F000000000000000000000000000000000B1\r
+S3156000EA0000000000000000000000000000000000A0\r
+S3156000EA100000000000000000000000000000000090\r
+S3156000EA200000000000000000000000000000000080\r
+S3156000EA300000000000000000000000000000000070\r
+S3156000EA400000000000000000000000000000000060\r
+S3156000EA500000000000000000000000000000000050\r
+S3156000EA600000000000000000000000000000000040\r
+S3156000EA700000000000000000000000000000000030\r
+S3156000EA800000000000000000000000000000000020\r
+S3156000EA900000000000000000000000000000000010\r
+S3156000EAA00000000000000000000000000000000000\r
+S3156000EAB000000000000000000000000000000000F0\r
+S3156000EAC000000000000000000000000000000000E0\r
+S3156000EAD000000000000000000000000000000000D0\r
+S3156000EAE000000000000000000000000000000000C0\r
+S3156000EAF000000000000000000000000000000000B0\r
+S3156000EB00000000000000000000000000000000009F\r
+S3156000EB10000000000000000000000000000000008F\r
+S3156000EB20000000000000000000000000000000007F\r
+S3156000EB30000000000000000000000000000000006F\r
+S3156000EB40000000000000000000000000000000005F\r
+S3156000EB50000000000000000000000000000000004F\r
+S3156000EB60000000000000000000000000000000003F\r
+S3156000EB70000000000000000000000000000000002F\r
+S3156000EB80000000000000000000000000000000001F\r
+S3156000EB90000000000000000000000000000000000F\r
+S3156000EBA000000000000000000000000000000000FF\r
+S3156000EBB000000000000000000000000000000000EF\r
+S3156000EBC000000000000000000000000000000000DF\r
+S3156000EBD000000000000000000000000000000000CF\r
+S3156000EBE000000000000000000000000000000000BF\r
+S3156000EBF000000000000000000000000000000000AF\r
+S3156000EC00000000000000000000000000000000009E\r
+S3156000EC10000000000000000000000000000000008E\r
+S3156000EC20000000000000000000000000000000007E\r
+S3156000EC30000000000000000000000000000000006E\r
+S3156000EC40000000000000000000000000000000005E\r
+S3156000EC50000000000000000000000000000000004E\r
+S3156000EC60000000000000000000000000000000003E\r
+S3156000EC70000000000000000000000000000000002E\r
+S3156000EC80000000000000000000000000000000001E\r
+S3156000EC90000000000000000000000000000000000E\r
+S3156000ECA000000000000000000000000000000000FE\r
+S3156000ECB000000000000000000000000000000000EE\r
+S3156000ECC000000000000000000000000000000000DE\r
+S3156000ECD000000000000000000000000000000000CE\r
+S3156000ECE000000000000000000000000000000000BE\r
+S3156000ECF000000000000000000000000000000000AE\r
+S3156000ED00000000000000000000000000000000009D\r
+S3156000ED10000000000000000000000000000000008D\r
+S3156000ED20000000000000000000000000000000007D\r
+S3156000ED30000000000000000000000000000000006D\r
+S3156000ED40000000000000000000000000000000005D\r
+S3156000ED50000000000000000000000000000000004D\r
+S3156000ED60000000000000000000000000000000003D\r
+S3156000ED70000000000000000000000000000000002D\r
+S3156000ED80000000000000000000000000000000001D\r
+S3156000ED90000000000000000000000000000000000D\r
+S3156000EDA000000000000000000000000000000000FD\r
+S3156000EDB000000000000000000000000000000000ED\r
+S3156000EDC000000000000000000000000000000000DD\r
+S3156000EDD000000000000000000000000000000000CD\r
+S3156000EDE000000000000000000000000000000000BD\r
+S3156000EDF000000000000000000000000000000000AD\r
+S3156000EE00000000000000000000000000000000009C\r
+S3156000EE10000000000000000000000000000000008C\r
+S3156000EE20000000000000000000000000000000007C\r
+S3156000EE30000000000000000000000000000000006C\r
+S3156000EE40000000000000000000000000000000005C\r
+S3156000EE50000000000000000000000000000000004C\r
+S3156000EE60000000000000000000000000000000003C\r
+S3156000EE70000000000000000000000000000000002C\r
+S3156000EE80000000000000000000000000000000001C\r
+S3156000EE90000000000000000000000000000000000C\r
+S3156000EEA000000000000000000000000000000000FC\r
+S3156000EEB000000000000000000000000000000000EC\r
+S3156000EEC000000000000000000000000000000000DC\r
+S3156000EED000000000000000000000000000000000CC\r
+S3156000EEE000000000000000000000000000000000BC\r
+S3156000EEF000000000000000000000000000000000AC\r
+S3156000EF00000000000000000000000000000000009B\r
+S3156000EF10000000000000000000000000000000008B\r
+S3156000EF20000000000000000000000000000000007B\r
+S3156000EF30000000000000000000000000000000006B\r
+S3156000EF40000000000000000000000000000000005B\r
+S3156000EF50000000000000000000000000000000004B\r
+S3156000EF60000000000000000000000000000000003B\r
+S3156000EF70000000000000000000000000000000002B\r
+S3156000EF80000000000000000000000000000000001B\r
+S3156000EF90000000000000000000000000000000000B\r
+S3156000EFA000000000000000000000000000000000FB\r
+S3156000EFB000000000000000000000000000000000EB\r
+S3156000EFC000000000000000000000000000000000DB\r
+S3156000EFD000000000000000000000000000000000CB\r
+S3156000EFE000000000000000000000000000000000BB\r
+S3156000EFF000000000000000000000000000000000AB\r
+S3156000F000000000000000000000000000000000009A\r
+S3156000F010000000000000000000000000000000008A\r
+S3156000F020000000000000000000000000000000007A\r
+S3156000F030000000000000000000000000000000006A\r
+S3156000F040000000000000000000000000000000005A\r
+S3156000F050000000000000000000000000000000004A\r
+S3156000F060000000000000000000000000000000003A\r
+S3156000F070000000000000000000000000000000002A\r
+S3156000F080000000000000000000000000000000001A\r
+S3156000F090000000000000000000000000000000000A\r
+S3156000F0A000000000000000000000000000000000FA\r
+S3156000F0B000000000000000000000000000000000EA\r
+S3156000F0C000000000000000000000000000000000DA\r
+S3156000F0D000000000000000000000000000000000CA\r
+S3156000F0E000000000000000000000000000000000BA\r
+S3156000F0F000000000000000000000000000000000AA\r
+S3156000F1000000000000000000000000000000000099\r
+S3156000F1100000000000000000000000000000000089\r
+S3156000F1200000000000000000000000000000000079\r
+S3156000F1300000000000000000000000000000000069\r
+S3156000F1400000000000000000000000000000000059\r
+S3156000F1500000000000000000000000000000000049\r
+S3156000F1600000000000000000000000000000000039\r
+S3156000F1700000000000000000000000000000000029\r
+S3156000F1800000000000000000000000000000000019\r
+S3156000F1900000000000000000000000000000000009\r
+S3156000F1A000000000000000000000000000000000F9\r
+S3156000F1B000000000000000000000000000000000E9\r
+S3156000F1C000000000000000000000000000000000D9\r
+S3156000F1D000000000000000000000000000000000C9\r
+S3156000F1E000000000000000000000000000000000B9\r
+S3156000F1F000000000000000000000000000000000A9\r
+S3156000F2000000000000000000000000000000000098\r
+S3156000F2100000000000000000000000000000000088\r
+S3156000F2200000000000000000000000000000000078\r
+S3156000F2300000000000000000000000000000000068\r
+S3156000F2400000000000000000000000000000000058\r
+S3156000F2500000000000000000000000000000000048\r
+S3156000F2600000000000000000000000000000000038\r
+S3156000F2700000000000000000000000000000000028\r
+S3156000F2800000000000000000000000000000000018\r
+S3156000F2900000000000000000000000000000000008\r
+S3156000F2A000000000000000000000000000000000F8\r
+S3156000F2B000000000000000000000000000000000E8\r
+S3156000F2C000000000000000000000000000000000D8\r
+S3156000F2D000000000000000000000000000000000C8\r
+S3156000F2E000000000000000000000000000000000B8\r
+S3156000F2F000000000000000000000000000000000A8\r
+S3156000F3000000000000000000000000000000000097\r
+S3156000F3100000000000000000000000000000000087\r
+S3156000F3200000000000000000000000000000000077\r
+S3156000F3300000000000000000000000000000000067\r
+S3156000F3400000000000000000000000000000000057\r
+S3156000F3500000000000000000000000000000000047\r
+S3156000F3600000000000000000000000000000000037\r
+S3156000F3700000000000000000000000000000000027\r
+S3156000F3800000000000000000000000000000000017\r
+S3156000F3900000000000000000000000000000000007\r
+S3156000F3A000000000000000000000000000000000F7\r
+S3156000F3B000000000000000000000000000000000E7\r
+S3156000F3C000000000000000000000000000000000D7\r
+S3156000F3D000000000000000000000000000000000C7\r
+S3156000F3E000000000000000000000000000000000B7\r
+S3156000F3F000000000000000000000000000000000A7\r
+S3156000F4000000000000000000000000000000000096\r
+S3156000F4100000000000000000000000000000000086\r
+S3156000F4200000000000000000000000000000000076\r
+S3156000F4300000000000000000000000000000000066\r
+S3156000F4400000000000000000000000000000000056\r
+S3156000F4500000000000000000000000000000000046\r
+S3156000F4600000000000000000000000000000000036\r
+S3156000F4700000000000000000000000000000000026\r
+S3156000F4800000000000000000000000000000000016\r
+S3156000F4900000000000000000000000000000000006\r
+S3156000F4A000000000000000000000000000000000F6\r
+S3156000F4B000000000000000000000000000000000E6\r
+S3156000F4C000000000000000000000000000000000D6\r
+S3156000F4D000000000000000000000000000000000C6\r
+S3156000F4E000000000000000000000000000000000B6\r
+S3156000F4F000000000000000000000000000000000A6\r
+S3156000F5000000000000000000000000000000000095\r
+S3156000F5100000000000000000000000000000000085\r
+S3156000F5200000000000000000000000000000000075\r
+S3156000F5300000000000000000000000000000000065\r
+S3156000F5400000000000000000000000000000000055\r
+S3156000F5500000000000000000000000000000000045\r
+S3156000F5600000000000000000000000000000000035\r
+S3156000F5700000000000000000000000000000000025\r
+S3156000F5800000000000000000000000000000000015\r
+S3156000F5900000000000000000000000000000000005\r
+S3156000F5A000000000000000000000000000000000F5\r
+S3156000F5B000000000000000000000000000000000E5\r
+S3156000F5C000000000000000000000000000000000D5\r
+S3156000F5D000000000000000000000000000000000C5\r
+S3156000F5E000000000000000000000000000000000B5\r
+S3156000F5F000000000000000000000000000000000A5\r
+S3156000F6000000000000000000000000000000000094\r
+S3156000F6100000000000000000000000000000000084\r
+S3156000F6200000000000000000000000000000000074\r
+S3156000F6300000000000000000000000000000000064\r
+S3156000F6400000000000000000000000000000000054\r
+S3156000F6500000000000000000000000000000000044\r
+S3156000F6600000000000000000000000000000000034\r
+S3156000F6700000000000000000000000000000000024\r
+S3156000F6800000000000000000000000000000000014\r
+S3156000F6900000000000000000000000000000000004\r
+S3156000F6A000000000000000000000000000000000F4\r
+S3156000F6B000000000000000000000000000000000E4\r
+S3156000F6C000000000000000000000000000000000D4\r
+S3156000F6D000000000000000000000000000000000C4\r
+S3156000F6E000000000000000000000000000000000B4\r
+S3156000F6F000000000000000000000000000000000A4\r
+S3156000F7000000000000000000000000000000000093\r
+S3156000F7100000000000000000000000000000000083\r
+S3156000F7200000000000000000000000000000000073\r
+S3156000F7300000000000000000000000000000000063\r
+S3156000F7400000000000000000000000000000000053\r
+S3156000F7500000000000000000000000000000000043\r
+S3156000F7600000000000000000000000000000000033\r
+S3156000F7700000000000000000000000000000000023\r
+S3156000F7800000000000000000000000000000000013\r
+S3156000F7900000000000000000000000000000000003\r
+S3156000F7A000000000000000000000000000000000F3\r
+S3156000F7B000000000000000000000000000000000E3\r
+S3156000F7C000000000000000000000000000000000D3\r
+S3156000F7D000000000000000000000000000000000C3\r
+S3156000F7E000000000000000000000000000000000B3\r
+S3156000F7F000000000000000000000000000000000A3\r
+S3156000F8000000000000000000000000000000000092\r
+S3156000F8100000000000000000000000000000000082\r
+S3156000F8200000000000000000000000000000000072\r
+S3156000F8300000000000000000000000000000000062\r
+S3156000F8400000000000000000000000000000000052\r
+S3156000F8500000000000000000000000000000000042\r
+S3156000F8600000000000000000000000000000000032\r
+S3156000F8700000000000000000000000000000000022\r
+S3156000F8800000000000000000000000000000000012\r
+S3156000F8900000000000000000000000000000000002\r
+S3156000F8A000000000000000000000000000000000F2\r
+S3156000F8B000000000000000000000000000000000E2\r
+S3156000F8C000000000000000000000000000000000D2\r
+S3156000F8D000000000000000000000000000000000C2\r
+S3156000F8E000000000000000000000000000000000B2\r
+S3156000F8F000000000000000000000000000000000A2\r
+S3156000F9000000000000000000000000000000000091\r
+S3156000F9100000000000000000000000000000000081\r
+S3156000F9200000000000000000000000000000000071\r
+S3156000F9300000000000000000000000000000000061\r
+S3156000F9400000000000000000000000000000000051\r
+S3156000F9500000000000000000000000000000000041\r
+S3156000F9600000000000000000000000000000000031\r
+S3156000F9700000000000000000000000000000000021\r
+S3156000F9800000000000000000000000000000000011\r
+S3156000F9900000000000000000000000000000000001\r
+S3156000F9A000000000000000000000000000000000F1\r
+S3156000F9B000000000000000000000000000000000E1\r
+S3156000F9C000000000000000000000000000000000D1\r
+S3156000F9D000000000000000000000000000000000C1\r
+S3156000F9E000000000000000000000000000000000B1\r
+S3156000F9F000000000000000000000000000000000A1\r
+S3156000FA000000000000000000000000000000000090\r
+S3156000FA100000000000000000000000000000000080\r
+S3156000FA200000000000000000000000000000000070\r
+S3156000FA300000000000000000000000000000000060\r
+S3156000FA400000000000000000000000000000000050\r
+S3156000FA500000000000000000000000000000000040\r
+S3156000FA600000000000000000000000000000000030\r
+S3156000FA700000000000000000000000000000000020\r
+S3156000FA800000000000000000000000000000000010\r
+S3156000FA900000000000000000000000000000000000\r
+S3156000FAA000000000000000000000000000000000F0\r
+S3156000FAB000000000000000000000000000000000E0\r
+S3156000FAC000000000000000000000000000000000D0\r
+S3156000FAD000000000000000000000000000000000C0\r
+S3156000FAE000000000000000000000000000000000B0\r
+S3156000FAF000000000000000000000000000000000A0\r
+S3156000FB00000000000000000000000000000000008F\r
+S3156000FB10000000000000000000000000000000007F\r
+S3156000FB20000000000000000000000000000000006F\r
+S3156000FB30000000000000000000000000000000005F\r
+S3156000FB40000000000000000000000000000000004F\r
+S3156000FB50000000000000000000000000000000003F\r
+S3156000FB60000000000000000000000000000000002F\r
+S3156000FB70000000000000000000000000000000001F\r
+S3156000FB80000000000000000000000000000000000F\r
+S3156000FB9000000000000000000000000000000000FF\r
+S3156000FBA000000000000000000000000000000000EF\r
+S3156000FBB000000000000000000000000000000000DF\r
+S3156000FBC000000000000000000000000000000000CF\r
+S3156000FBD000000000000000000000000000000000BF\r
+S3156000FBE000000000000000000000000000000000AF\r
+S3156000FBF0000000000000000000000000000000009F\r
+S3156000FC00000000000000000000000000000000008E\r
+S3156000FC10000000000000000000000000000000007E\r
+S3156000FC20000000000000000000000000000000006E\r
+S3156000FC30000000000000000000000000000000005E\r
+S3156000FC40000000000000000000000000000000004E\r
+S3156000FC50000000000000000000000000000000003E\r
+S3156000FC60000000000000000000000000000000002E\r
+S3156000FC70000000000000000000000000000000001E\r
+S3156000FC80000000000000000000000000000000000E\r
+S3156000FC9000000000000000000000000000000000FE\r
+S3156000FCA000000000000000000000000000000000EE\r
+S3156000FCB000000000000000000000000000000000DE\r
+S3156000FCC000000000000000000000000000000000CE\r
+S3156000FCD000000000000000000000000000000000BE\r
+S3156000FCE000000000000000000000000000000000AE\r
+S3156000FCF0000000000000000000000000000000009E\r
+S3156000FD00000000000000000000000000000000008D\r
+S3156000FD10000000000000000000000000000000007D\r
+S3156000FD20000000000000000000000000000000006D\r
+S3156000FD30000000000000000000000000000000005D\r
+S3156000FD40000000000000000000000000000000004D\r
+S3156000FD50000000000000000000000000000000003D\r
+S3156000FD60000000000000000000000000000000002D\r
+S3156000FD70000000000000000000000000000000001D\r
+S3156000FD80000000000000000000000000000000000D\r
+S3156000FD9000000000000000000000000000000000FD\r
+S3156000FDA000000000000000000000000000000000ED\r
+S3156000FDB000000000000000000000000000000000DD\r
+S3156000FDC000000000000000000000000000000000CD\r
+S3156000FDD000000000000000000000000000000000BD\r
+S3156000FDE000000000000000000000000000000000AD\r
+S3156000FDF0000000000000000000000000000000009D\r
+S3156000FE00000000000000000000000000000000008C\r
+S3156000FE10000000000000000000000000000000007C\r
+S3156000FE20000000000000000000000000000000006C\r
+S3156000FE30000000000000000000000000000000005C\r
+S3156000FE40000000000000000000000000000000004C\r
+S3156000FE50000000000000000000000000000000003C\r
+S3156000FE60000000000000000000000000000000002C\r
+S3156000FE70000000000000000000000000000000001C\r
+S3156000FE80000000000000000000000000000000000C\r
+S3156000FE9000000000000000000000000000000000FC\r
+S3156000FEA000000000000000000000000000000000EC\r
+S3156000FEB000000000000000000000000000000000DC\r
+S3156000FEC000000000000000000000000000000000CC\r
+S3156000FED000000000000000000000000000000000BC\r
+S3156000FEE000000000000000000000000000000000AC\r
+S3156000FEF0000000000000000000000000000000009C\r
+S3156000FF00000000000000000000000000000000008B\r
+S3156000FF10000000000000000000000000000000007B\r
+S3156000FF20000000000000000000000000000000006B\r
+S3156000FF30000000000000000000000000000000005B\r
+S3156000FF40000000000000000000000000000000004B\r
+S3156000FF50000000000000000000000000000000003B\r
+S3156000FF60000000000000000000000000000000002B\r
+S3156000FF70000000000000000000000000000000001B\r
+S3156000FF80000000000000000000000000000000000B\r
+S3156000FF9000000000000000000000000000000000FB\r
+S3156000FFA000000000000000000000000000000000EB\r
+S3156000FFB000000000000000000000000000000000DB\r
+S3156000FFC000000000000000000000000000000000CB\r
+S3156000FFD000000000000000000000000000000000BB\r
+S3156000FFE000000000000000000000000000000000AB\r
+S3156000FFF0000000000000000000000000000000009B\r
+S315600100000000000000000000000000000000000089\r
+S315600100100000000000000000000000000000000079\r
+S315600100200000000000000000000000000000000069\r
+S315600100300000000000000000000000000000000059\r
+S315600100400000000000000000000000000000000049\r
+S315600100500000000000000000000000000000000039\r
+S315600100600000000000000000000000000000000029\r
+S315600100700000000000000000000000000000000019\r
+S315600100800000000000000000000000000000000009\r
+S3156001009000000000000000000000000000000000F9\r
+S315600100A000000000000000000000000000000000E9\r
+S315600100B000000000000000000000000000000000D9\r
+S315600100C000000000000000000000000000000000C9\r
+S315600100D000000000000000000000000000000000B9\r
+S315600100E000000000000000000000000000000000A9\r
+S315600100F00000000000000000000000000000000099\r
+S315600101000000000000000000000000000000000088\r
+S315600101100000000000000000000000000000000078\r
+S315600101200000000000000000000000000000000068\r
+S315600101300000000000000000000000000000000058\r
+S315600101400000000000000000000000000000000048\r
+S315600101500000000000000000000000000000000038\r
+S315600101600000000000000000000000000000000028\r
+S315600101700000000000000000000000000000000018\r
+S315600101800000000000000000000000000000000008\r
+S3156001019000000000000000000000000000000000F8\r
+S315600101A000000000000000000000000000000000E8\r
+S315600101B000000000000000000000000000000000D8\r
+S315600101C000000000000000000000000000000000C8\r
+S315600101D000000000000000000000000000000000B8\r
+S315600101E000000000000000000000000000000000A8\r
+S315600101F00000000000000000000000000000000098\r
+S315600102000000000000000000000000000000000087\r
+S315600102100000000000000000000000000000000077\r
+S315600102200000000000000000000000000000000067\r
+S315600102300000000000000000000000000000000057\r
+S315600102400000000000000000000000000000000047\r
+S315600102500000000000000000000000000000000037\r
+S315600102600000000000000000000000000000000027\r
+S315600102700000000000000000000000000000000017\r
+S315600102800000000000000000000000000000000007\r
+S3156001029000000000000000000000000000000000F7\r
+S315600102A000000000000000000000000000000000E7\r
+S315600102B000000000000000000000000000000000D7\r
+S315600102C000000000000000000000000000000000C7\r
+S315600102D000000000000000000000000000000000B7\r
+S315600102E000000000000000000000000000000000A7\r
+S315600102F00000000000000000000000000000000097\r
+S315600103000000000000000000000000000000000086\r
+S315600103100000000000000000000000000000000076\r
+S315600103200000000000000000000000000000000066\r
+S315600103300000000000000000000000000000000056\r
+S315600103400000000000000000000000000000000046\r
+S315600103500000000000000000000000000000000036\r
+S315600103600000000000000000000000000000000026\r
+S315600103700000000000000000000000000000000016\r
+S315600103800000000000000000000000000000000006\r
+S3156001039000000000000000000000000000000000F6\r
+S315600103A000000000000000000000000000000000E6\r
+S315600103B000000000000000000000000000000000D6\r
+S315600103C000000000000000000000000000000000C6\r
+S315600103D000000000000000000000000000000000B6\r
+S315600103E000000000000000000000000000000000A6\r
+S315600103F00000000000000000000000000000000096\r
+S315600104000000000000000000000000000000000085\r
+S315600104100000000000000000000000000000000075\r
+S315600104200000000000000000000000000000000065\r
+S315600104300000000000000000000000000000000055\r
+S315600104400000000000000000000000000000000045\r
+S315600104500000000000000000000000000000000035\r
+S315600104600000000000000000000000000000000025\r
+S315600104700000000000000000000000000000000015\r
+S315600104800000000000000000000000000000000005\r
+S7050000684052\r
diff --git a/tools/elftosb/test_files/test0.key b/tools/elftosb/test_files/test0.key
new file mode 100644 (file)
index 0000000..19af2fa
--- /dev/null
@@ -0,0 +1 @@
+F8B5A7C69EE6F795513B12227163A79C
diff --git a/tools/elftosb/winsupport/unistd.h b/tools/elftosb/winsupport/unistd.h
new file mode 100644 (file)
index 0000000..e69de29
index bf9d935efdca205328de190f911d70c6ac594df2..937ed35401a6a2a2451244ed960296075541fc5a 100644 (file)
@@ -15,7 +15,7 @@ main(int argc, char *argv[])
 {
     unsigned long ethaddr_low, ethaddr_high;
 
-    srand(time(0) | getpid());
+    srand(rand() ^ time(0) ^ getpid());
 
     /*
      * setting the 2nd LSB in the most significant byte of
diff --git a/tools/logos/karo.bmp b/tools/logos/karo.bmp
new file mode 100644 (file)
index 0000000..001cca7
Binary files /dev/null and b/tools/logos/karo.bmp differ